Моя система (3.2.0-52-generic, g ++ - 4.7 (Ubuntu / Linaro 4.7.3-2ubuntu1 ~ 12.04) 4.7.3, скомпилировано с -O2 , если не указано, CPU: i3 -2125)
В моих тестовых случаях я использовал словарь 295068 слов (так что слов на 100 000 больше, чем в вашем): http://dl.dropboxusercontent.com/u/4076606/words.txt
С точки зрения сложности времени:
- В худшем случае сложность вашей программы: O (n * n) = O (n [читать данные] * n [вставить в unordered_set])
- Среднее значение сложности вашей программы: O (n) = O (n [читать данные] * 1 [вставить в unordered_set])
Практические советы:
- В большинстве простых структур данных меньше затрат времени. Простой массив быстрее, чем вектор. массив символов быстрее строки. В Интернете много информации об этом.
Мои измерения:
Примечание: я не очищал кэш ОС и кеш жесткого диска. Последнее, что я не могу контролировать, но первым можно управлять с помощью:
sync; sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
Также я не пропустил те измерения, которые включали много переключений контекста и так далее. Таким образом, есть место для более точных измерений.
Мой код:
14–16 мс для чтения из файла и вставки данных в массив символов 2D (чтение и вставка) n раз
65-75 мс для поиска с помощью двоичный поиск все слова ( поиск n раз ):
Всего = 79-91 мс
61-78 мс для чтения из файла и вставки данных в массив символов unordered_set (чтение и вставка) n раз
7-9 мс до поиск по хэшу n раз
Всего = 68-87 мс
Если вы выполняете поиск больше раз, чем вставляете, выберите хэш-таблицу (unordered_set), в противном случае бинарный поиск (с простым массивом).
Ваш оригинальный код (поиск и вставка):
Скомпилировано с -O2: 157-182 мс
Скомпилировано с -O0 (если вы опустите флаг -O, уровень "-O" по умолчанию также равен 0): 223-248 мс
Итак, опции компилятора также имеют значение, в данном случае это означает 66 мс ускорение скорости . Вы не указали ни один из них. Так что, я думаю, ты не использовал это. Как я пытаюсь ответить на ваш главный вопрос.
Что вы можете сделать проще всего, но лучше с вашим текущим кодом?
- [лучшее использование API высокого уровня] Используйте «getline (wordListFile, word)» вместо «wordListFile >> word». Также я думаю, что "getline" более читабелен, чем оператор ">>".
Скомпилировано с -O2: 142-170 мс. Увеличение скорости ~ 12-15 мс по сравнению с исходным кодом.
Скомпилировано с -O0 (если вы опустите флаг -O, уровень "-O" по умолчанию также равен 0): 213-235 мс. ~ 10-13 мс ускорения по сравнению с исходным кодом.
- [лучшее использование API высокого уровня] Избегайте перефразирования с помощью «dict.reserve (XXXXXX);», @David Rodríguez - dribeas также упоминал об этом. Если ваш словарь статический или вы можете угадать его размер словаря (например, по размеру файла, деленному на среднюю длину слова) Сначала запустите без «резерва» и выведите bucket_count (cout << «bucket_count =» << dict.bucket_count () << «\ n»;), в моем случае это 299951. Затем я добавил «dict.reserve (299951) ;.»</li>
Скомпилировано с -O2: 99-121- [137] мс. ~ 33-43- [49] мс ускорение скорости по сравнению с исходным кодом.
Что вы можете сделать более продвинутым, чтобы ускорить его?
Реализуйте свою собственную хеш-функцию для вашего конкретного ввода данных. Используйте массив символов вместо строки STL. После того, как вы это сделали, только потом пишите код с прямым вводом-выводом ОС. Как вы заметили (из моих измерений также видно), что структура данных является узким местом. Если носитель очень медленный, но процессор очень быстрый, сожмите файл, распакуйте его в вашей программе.
Мой код не идеален, но все же он лучше, чем что-либо, что можно увидеть выше: http://pastebin.com/gQdkmqt8 (хеш-функция из Интернета, также может быть лучше)
Не могли бы вы предоставить более подробную информацию о том, какую систему (одну или диапазон) вы планируете оптимизировать?
Информация о сложности времени: Должны быть ссылки ... Но у меня не так много репутации, как у меняЯ новичок в stackoverflow.
Мой ответ по-прежнему имеет отношение к чему-либо?Пожалуйста, добавьте комментарий или голосуйте, поскольку я не вижу PM, как я вижу.