Сравнительный анализ команд Bash со временем и ти

434
Hashim

У меня есть каталог, содержащий более 80 ГБ баз данных простых текстовых файлов, которые, как я ожидаю, придется часто просматривать. По этой причине я пытаюсь создать несколько тестов для сравнения GNU grepс тем, что, насколько я могу судить, является самой быстрой альтернативой ему в настоящее время в дикой природе - ripgrep - чтобы определить, какой из них будет работать быстрее всего с моим данные.

Первый тест будет состоять из трех forциклов, которые выполняются grep, rgи grep -Fдля текстового файла объемом 15 ГБ, а второй тест будет представлять собой серию одинаковых команд, выполняемых для всех данных. После нескольких дней постоянных циклов между использованием моих собственных ограниченных bashзнаний, поиском решений и устранением ошибок, мне удалось собрать воедино следующее для первого теста (который также будет переназначен для второго теста):

for i in ; \ do (time LC_ALL=C grep -i "ajndoandajskaskaksnaodnasnakdnaosnaond" "15gbfile.txt") 2>&1 |  tee -a "../grep Test 1.txt"; \ done; \ for i in ; \ do (time rg -i "ajndoandajskaskaksnaodnasnakdnaosnaond" "15gbfile.txt") 2>&1 | tee -a "../ripgrep Test 1.txt"; \ done; for i in ; \ do (time LC_ALL=C grep -Fi "ajndoandajskaskaksnaodnasnakdnaosnaond" "15gbfile.txt") 2>&1 | tee -a "../grep -F Test 1.txt"; \ done; 

Это некрасиво, но работает точно так, как задумано. Он выполняет все три forцикла один за другим, каждый из которых выполняет поиск 15 раз для длинной строки, которая никогда не будет найдена, а затем печатает вывод timeкаждого из них grepв оба STDOUTфайла и в файл.

Однако, поскольку я бенчмаркинг, я хочу убедиться, что код подходит для точного тестирования (относительной) скорости моих вариантов использования в системе POSIX / bash / Cygwin, и что я ничего не пропускаю, что могло бы исказить результаты я получаю. В частности, такие вещи, как кэширование, дисковый ввод-вывод и другие соображения, о которых я не знаю. Я также приветствовал бы любые предложения, которые заставили бы его вести себя более надежно \ выглядеть менее уродливым.

1
Как насчет кеширования? Часть 15-гигабайтного файла будет в памяти после того, как первый цикл войдет во второй, что может сделать второй цикл искусственно быстрее. Интересно поработать с этим и без него, чтобы увидеть, в чем разница: https://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/ Paul 6 лет назад 1
@Paul Это основная причина, по которой я запускал `grep` 15 раз для каждого, полагая, что кэширование будет иметь значение только во времени для первого или двух прогонов. Разве это не так? Hashim 6 лет назад 0
Этот тест определенно не соответствует проблеме, которую вы пытаетесь решить. Во-первых, если вы ищите 80 ГБ файлов, то, скорее всего, некоторую большую их часть нужно будет прочитать с диска. grep и ripgrep будут делать это примерно с одинаковой скоростью, потому что оба они, вероятно, имеют узкое место по скорости ввода / вывода для простых шаблонов. Во-вторых, ripgrep будет сканировать каталог параллельно по умолчанию, а `grep -r` - нет. Это может привести к лучшему времени поиска, которое не будет записано при поиске в одном файле. BurntSushi5 6 лет назад 2
@ BurntSushi5 Возможно, стоит рассказать, что вы разработчик `ripgrep`, но я понимаю вашу точку зрения. Как упоминалось в посте, это просто первый тест, который я собираюсь запустить. Вторым тестом будет запуск команд по всему каталогу. Большая часть моего намерения заключалась в том, чтобы просто убедиться, что в самом коде нет ошибок, чтобы его можно было переназначить для второго теста. Hashim 6 лет назад 0
@Paul Мне пришла в голову мысль: все ли это применимо к Cygwin, работающему поверх системы Windows 7? Я не уверен, что Cygwin bash выполняет кеширование. Hashim 6 лет назад 0
@ Хашим, я точно не знаю, но сомневаюсь. Что касается вашего другого вопроса, при входе в первый цикл файл будет кэширован, тогда как в начале цикла ripgrep он потенциально будет кэширован. Так что это дает петле ripgrep преимущество. Paul 6 лет назад 0
@Paul Решит ли эту проблему выполнение каждой команды подряд в одном цикле for, как предполагает его ответ? Примерно так: https://pastebin.com/L2ua3ihP? Hashim 6 лет назад 0
@Hashim Извините, но я не собираюсь говорить, что являюсь автором ripgrep каждый раз, когда хочу рассказать о ripgrep в Интернете. Я раскрою это, когда я думаю, что это разумно, но я иначе думаю, что легко обнаружить, если люди заботятся. Cygwin - это не то, что делает кеширование; ОС будет. Если вы хотите выполнить базовый «первый» тест, выберите файл меньшего размера или найдите способ гарантировать, что ваш файл объемом 15 ГБ всегда будет в памяти (прикрепив его к виртуальному диску). В противном случае ваш тест просто будет подвержен стратегии кэширования ОС. BurntSushi5 6 лет назад 0
@Hashim Если вы хотите более изощренный способ сравнения инструментов командной строки, подумайте об использовании Hyperfine: https://github.com/sharkdp/hyperfine --- В противном случае создание «базового» первого теста мне явно не поможет если ваш второй тест будет использовать совершенно другой тип поиска с другим поведением. Сравнительный анализ случая, когда все находится в памяти, по сравнению со случаем, когда вам нужно читать с диска, требует двух разных стратегий, и они, в свою очередь, зависят от того, что вы хотите измерить. BurntSushi5 6 лет назад 0
@ BurntSushi5 Что касается вашего первого комментария - значит, цель не в том, чтобы устранить кеширование, а в том, чтобы обеспечить его согласованность на протяжении всех тестов? Hashim 6 лет назад 0
@ Хашим, в идеальном смысле, конечно. Но я не понимаю, как это возможно, так как это прозрачная вещь, обрабатываемая ОС. На практике у вас есть два варианта: либо убедиться, что все находится в кеше, либо убедиться, что в нем ничего нет. Первое может быть достигнуто в основном путем достаточного прогрева или размещения входа на виртуальном диске, * предполагая, что ваш ввод помещается в память. (Разве это? 15 ГБ, вероятно, не будет полностью кэшироваться в системе с 16 ГБ памяти.) Последнее обычно возможно, хотя я знаю только, как это сделать в Linux: `sudo sh -c 'echo 3> / proc / SYS / VM / drop_caches'`. BurntSushi5 6 лет назад 0
@ BurntSushi5 Будет ли использование достаточно большого файла гарантировать, что в кеше ничего нет? Скажите файл 30 ГБ в системе с 16 ГБ памяти? Или файл будет просто кэшироваться по частям? Hashim 6 лет назад 0
Я думаю, что я дал вам только два варианта, которые, как я знаю, достаточно надежны для серьезного и воспроизводимого бенчмаркинга. Я не вижу причин предполагать, что файл либо полностью кэширован, либо полностью не кэширован. BurntSushi5 6 лет назад 1

1 ответ на вопрос

1
xenoid

ИМХО, вы тестируете предвзято, потому что вы запускаете три команды в разное время. У вас должен быть один цикл, который последовательно выполняет команды grep, rgrep, grep -F, и если вы можете сделать этот порядок случайным, это будет даже лучше.

С другой стороны, производительность - это еще не все, и мне потребовалось бы значительно более высокое быстродействие, чтобы переключиться на конкретную команду, и этот гораздо лучший исполнитель показал бы это даже при предвзятых тестах.

Кроме того, команда `tee`, вероятно, занимает больше времени, чем` grep` matzeri 6 лет назад 0
Я вижу вашу точку зрения в первом абзаце, но как это повлияет на устранение преимуществ кэширования? Мое первоначальное намерение последовательно выполнять одни и те же команды заключалось в том, что кэширование будет применяться к первым нескольким экземплярам команды, и поэтому эти первые несколько запусков можно было игнорировать. Кроме того, применимы ли в Linux концепции кэширования / дискового ввода-вывода к `bash`, работающему в Cygwin поверх Windows 7? Hashim 6 лет назад 0
Кэширование файлов не является «концепцией Linux». BurntSushi5 6 лет назад 0
@ BurntSushi5 Я никогда не утверждал, что это так, но две ОС, вероятно, имеют разные реализации / подходы к нему, и я спрашивал, будет ли «bash», работающий в Cygwin, использовать Linux или Windows ». Hashim 6 лет назад 0

Похожие вопросы