Skip to content

Commit 7f23279

Browse files
committed
v0.25
1 parent b9324e6 commit 7f23279

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ЗАМЕТКИ ПО РЕШЕНИЮ
2+
3+
## Процесс решения
4+
5+
Во-первых было интересно, спасибо! :)
6+
Выполнение заняло сильно больше времени, чем я изначально оценил.
7+
8+
Было весьма унизительно, когда первая версия казалось бы очень оптимизированного решения со всякими
9+
статически выделенными массивами без перевыделений памяти оказалась медленнее grep раз в 5-6.
10+
А я ожидал, что резальтат уже должен быть лучше аналогов. Тем более, что у меня специализированный алгоритм,
11+
а у grep синтаксис иной и алгоритм по определению хуже должен быть.
12+
13+
Потом я заменил алгоритм матча строки с динамическим программированием и памятью O(P*N) на другой, более быстрый и с константной памятью.
14+
И... я стал медленнее grep всего в 2 раза. Почти успех :))) При этом по профайлеру релизному у меня 80+% проводилось именно в матче строк.
15+
16+
Не буду томить, сомневаюсь, что более эффективный алгоритм существует для этой задачи.
17+
Победить grep вышло лишь добавив несколько оптимизаций, которые просто ускоренно прокручивали алгоритм в популярных сценариях.
18+
И эта победа всего лишь на 25%.
19+
20+
После этого согласно профайлеру почти ровно половина времени проводилась
21+
в матче строк, а процентов под 40 времени проводилось в синхронном ReadFile().
22+
23+
Я решил, что вот он звёздный час асинхронного чтения файлов!
24+
Запрограмировал, и... ничего. Общее время работы не изменилось.
25+
Но профайлер показал перераспределение времени в сторону алгоритма матча. Очень странно. Я так и не понял почему так.
26+
Я убеждён, что эти 40% можно было сжать до максимум 5% за что параллелизации вычитки данных и их обработки.
27+
28+
Попробовал на всякий случай отображать файл на память.
29+
Но у меня были сомнения в эффективности для этого применения.
30+
Так и вышло. Немного медленнее. Примерно как grep вышло.
31+
32+
## Тестирование и заметки
33+
34+
Тестировал на логе веб сервера, 2 Гб, 5.5 млн строк, средняя длина строки 380 байт, все строки не длинее 1024 байт.
35+
36+
Диск SSD, но прогревал чтобы всё в кэш легло файловый. 8 ядер логических core i5 gen8, прочей загрузки минимум, ноутбук.
37+
38+
Сборка под x64 архитектуру работала быстрее вышла чем под x86.
39+
40+
Флаг FILE_FLAG_SEQUENTIAL_SCAN к моему разочарованию не дал ничего.
41+
42+
Иногда скорость надолго залипает на +25%, иногда на самом быстром варианте.
43+
Скорее всего связано с тем, что у меня ноутбук и у ядер есть режимы экономные. Но не факт.
44+
45+
## Особенности реализации
46+
47+
В итоге у меня остались все три реализации чтения файлов. Я оставил асинхронную версию как самую перспективную. Переключаются так:
48+
49+
```
50+
#if 1
51+
#if 0
52+
CSyncLineReader _lineReader;
53+
#else
54+
CAsyncLineReader _lineReader;
55+
#endif
56+
#else
57+
CMappingLineReader _lineReader;
58+
#endif
59+
```
60+
61+
Также есть юнит тесты на базе gtest с отдельным проектом.
62+
63+
Как и в условии задачи, основное консольное приложение собрано с отключенными исключениями и заодно без RTTI.
64+
65+
Я притянул часть STL на мой страх и риск. Ту, часть, которая не требует исключений и работает без лишних накладных расходов.
66+

0 commit comments

Comments
 (0)