2016-07-17 6 views
-5

EDIT: Я заметил, что, как я делаю некоторые изменения, как было предложено ниже, программа использует только 12% CPU и едва ли читает/записывает, но все-таки медленно, я запускал программа на 4 файла одновременно с помощью потоков, делая чуть меньше 4х работы и используя 62% процессор, у меня есть таймер 100 мс, обновляющий индикатор выполнения и метку. Не может ли это повлиять на производительность? Эта конкретная программа выполняет только одну задачу, поэтому имеет метку, таймер и индикатор выполнения, каждый раз, когда файл поступает к нему.Есть ли более эффективный способ сравнения строки

У меня есть 655 000 слов "Слова" в файле. Я хочу перекрестно ссылаться на предоставленное пользователем «слово», чтобы узнать, могу ли я найти совпадение в файле.

В настоящее время я просто открываю файл и читаю строки за строкой, проверяя, совпадают ли значения.

Но это занимает много времени, чтобы просмотреть файл.

Есть ли более быстрый способ делать сравнения? Должен ли я прочитать весь файл, потом разделить и сравнить?

Я попытался «проиндексировать» файл слова, но это также берет навсегда. Код ниже

я запустить его в отдельном потоке

Файл растет очень быстро, за два часа назад это было 10000 «Слова» я бы предположить, что это будет попасть в 10-х миллионов

Я использую термин «Слова», потому что файл содержит данные из моего первого нейросетевого ИИ, поэтому ссылка на поиск слов не будет работать, к сожалению.

Do While sr.Peek() >= 0 
     NewWord = (sr.ReadLine()) 
     FirstLetter = NewWord(0) 
     Wordlength = NewWord.Length 

     If Wordlength < 5 Then 
      writefile = "5.txt" 
     End If 
     If Wordlength = 6 Then 
      writefile = "6.txt" 
     End If 
     If Wordlength = 7 Then 
      writefile = "7.txt" 
     End If 
     If Wordlength = 8 Then 
      writefile = "8.txt" 
     End If 
     If Wordlength = 9 Then 
      writefile = "9.txt" 
     End If 
     If Wordlength = 10 Then 
      writefile = "10.txt" 
     End If 
     If Wordlength = 11 Then 
      writefile = "11.txt" 
     End If 
     If Wordlength >= 12 Then 
      writefile = "12.txt" 
     End If 


     If LCase(FirstLetter) = "a" Then 
      Writepath = "H:\Dictionary\A\" 
     End If 
     If LCase(FirstLetter) = "b" Then 
      Writepath = "H:\Dictionary\B\" 
     End If 
     If LCase(FirstLetter) = "c" Then 
      Writepath = "H:\Dictionary\C\" 
     End If 
     If LCase(FirstLetter) = "d" Then 
      Writepath = "H:\Dictionary\D\" 
     End If 
     If LCase(FirstLetter) = "e" Then 
      Writepath = "H:\Dictionary\E\" 
     End If 
     If LCase(FirstLetter) = "f" Then 
      Writepath = "H:\Dictionary\F\" 
     End If 
     If LCase(FirstLetter) = "g" Then 
      Writepath = "H:\Dictionary\G\" 
     End If 
     If LCase(FirstLetter) = "h" Then 
      Writepath = "H:\Dictionary\H\" 
     End If 
     If LCase(FirstLetter) = "i" Then 
      Writepath = "H:\Dictionary\I\" 
     End If 
     If LCase(FirstLetter) = "j" Then 
      Writepath = "H:\Dictionary\J\" 
     End If 
     If LCase(FirstLetter) = "k" Then 
      Writepath = "H:\Dictionary\K\" 
     End If 
     If LCase(FirstLetter) = "l" Then 
      Writepath = "H:\Dictionary\L\" 
     End If 
     If LCase(FirstLetter) = "m" Then 
      Writepath = "H:\Dictionary\M\" 
     End If 
     If LCase(FirstLetter) = "n" Then 
      Writepath = "H:\Dictionary\N\" 
     End If 
     If LCase(FirstLetter) = "o" Then 
      Writepath = "H:\Dictionary\O\" 
     End If 
     If LCase(FirstLetter) = "p" Then 
      Writepath = "H:\Dictionary\P\" 
     End If 
     If LCase(FirstLetter) = "q" Then 
      Writepath = "H:\Dictionary\Q\" 
     End If 
     If LCase(FirstLetter) = "r" Then 
      Writepath = "H:\Dictionary\R\" 
     End If 
     If LCase(FirstLetter) = "s" Then 
      Writepath = "H:\Dictionary\S\" 
     End If 
     If LCase(FirstLetter) = "t" Then 
      Writepath = "H:\Dictionary\T\" 
     End If 
     If LCase(FirstLetter) = "u" Then 
      Writepath = "H:\Dictionary\U\" 
     End If 
     If LCase(FirstLetter) = "v" Then 
      Writepath = "H:\Dictionary\V\" 
     End If 
     If LCase(FirstLetter) = "w" Then 
      Writepath = "H:\Dictionary\W\" 
     End If 
     If LCase(FirstLetter) = "x" Then 
      Writepath = "H:\Dictionary\X\" 
     End If 
     If LCase(FirstLetter) = "y" Then 
      Writepath = "H:\Dictionary\Y\" 
     End If 
     If LCase(FirstLetter) = "z" Then 
      Writepath = "H:\Dictionary\Z\" 
     End If 

     outputpath = Writepath & writefile 



     Using sw As StreamWriter = File.AppendText(outputpath) 
      sw.WriteLine(NewWord) 
     End Using 
     progressvalue = progressvalue + 1 
    Loop 
+2

Я бы прочитал файл в HashSet и посмотрел туда. Если вы обнаружите, что число слов значительно возрастает, вы можете захотеть изучить базу данных вместо локального плоского файла. – keyboardP

+0

Я бы заменил все эти 'If' на' Select Case', поэтому ему не нужно будет проверять все остальные условия. – Filburt

+0

Спасибо, я думал о базе данных, но в конечном файле будет 1.4534931852847813494150390625e + 58 Записи, я использую много узлов для проверки небольших фрагментов файлов, поэтому зачем пытаться разбить. Я изучил тип программирования, необходимый для такого подвига, и я не мог понять его. Теперь я посмотрю на hashset, Thankyou –

ответ

1

структура Hash данных (например, HashSet в .NET) будет самый быстрый способ добавить и проверить слова, но это будет в конечном итоге запустить из памяти, как вы добавите больше слов.

База данных должна быть лучшей, поскольку слова будут проиндексированы, и вы можете получить к ней доступ с нескольких компьютеров.

Использование файловой системы для этого, скорее всего, будет самым медленным способом, но я предполагаю, что использование имен папок вместо файлов должно быть быстрее. Например, для слова Foo путь будет "H:\Dictionary\F\O\O\" (верхний или строчный регистр не имеет значения для большинства популярных файловых систем, о которых я знаю), но он также будет использовать гораздо больше места, поскольку каждая папка будет иметь отдельные данные и настройки метаданных.

Если у проекта есть бюджет, вы можете искать лучшие решения, такие как Google BigQuery.

+0

Если он хочет поддерживать уникальный набор, Hashset лучше, чем HashTable, поскольку он не позволяет использовать значения dup ... Также HashTable синхронизируется и имеет стоимость, и к ним можно получить доступ только по одному потоку за раз, что ограничивало бы скорость проверки слов значительно. – Codexer

+0

@ Zaggler Я имею в виду это как общую концепцию, не ограниченную платформой .NET, но я не уверен, что было бы самым очевидным для нее термином. – Slai

Смежные вопросы