Bash: медленнее использовать zcat по сравнению с cat+zcat или cat+pv+zcat

Я обрабатываю несколько больших заархивированных файлов и обнаружил кое-что интересное, чего я не понимаю: использование cat+pv+zcat быстрее, чем cat+zcat, которое быстрее, чем использование только zcat.

Для этого я использую заархивированный JSON-файл размером 1 ГБ в качестве теста.

time cat test.json.gz > /dev/null
time zcat test.json.gz > /dev/null
time cat test.json.gz | zcat > /dev/null
time cat test.json.gz | pv | zcat > /dev/null
real    0m8.245s
real    0m33.075s
real    0m30.504s
real    0m26.682s

Аналогично при записи в файл:

time cat test.json.gz > t0.json.gz
time zcat test.json.gz > t1.json
time cat test.json.gz | zcat > t2.json
time cat test.json.gz | pv | zcat > t3.json
real    0m21.053s
real    0m59.011s
real    0m57.110s
real    0m54.439s

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

Обычно я считаю, что несколько шагов в конвейере увеличивают время, необходимое для обработки файла, так почему же добавление pv может ускорить процесс? Имеет ли он какое-то встроенное распараллеливание? Что здесь происходит?

Если это ожидаемое поведение, я только что наткнулся на очень простой способ увеличить скорость обработки на 10%, но мне бы хотелось понять, что происходит.

«Обычно я рассматриваю несколько шагов в канале как увеличение времени, необходимого для обработки файла» — не обязательно. Вы потенциально получите достаточную выгоду от распараллеливания операций, чтобы преодолеть накладные расходы нескольких процессов. Дополнительный ввод-вывод не обязательно является проблемой, поскольку он выполняется параллельно. Кроме того, обычно можно ожидать, что ввод-вывод через канал будет намного дешевле, чем файловый ввод-вывод.

John Bollinger 30.08.2024 18:59

Я не могу это воспроизвести. zcat file для меня быстрее, чем cat file | zcat.

Nick ODell 30.08.2024 19:01
real может быть неправильным значением для измерения. подумайте time sleep 10
jhnc 30.08.2024 21:15

По крайней мере, для моей системы настоящее — это точно: time sleep 10 — это real 0m10.001s.

apprentice iron chef 31.08.2024 00:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обычно я считаю, что несколько шагов в конвейере увеличивают время, необходимое для обработки файла, так почему же добавление pv может ускорить процесс? Имеет ли он какое-то встроенное распараллеливание? Что здесь происходит?

На многоядерном процессоре вполне вероятно, что хотя бы иногда вы получаете настоящий параллелизм нескольких процессов. Даже если вы не получаете настоящего параллелизма, многопроцессорность действительно является формой параллельной обработки, так что да, некоторое распараллеливание происходит.

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

Конечно, какому-то процессу все равно нужно прочитать этот файл, но вполне возможно, что распаковка zcat + выходной ввод-вывод обходится дороже, чем (скажем) файловый ввод-вывод + конвейерный ввод-вывод cat. В таких обстоятельствах многопроцессорная обработка с помощью cat | zcat могла бы стать победой.

Еще более загадочно, почему вставка pv в конвейер между cat и zcat может улучшить производительность, но я предполагаю, что pv буферизует больше данных за раз, чем cat, так что с pv в середине zcat может прочитать данные в целом за меньшее количество операций чтения, каждое из которых больше. Это тоже потенциальный выигрыш в производительности. Вполне вероятно, что канальный ввод-вывод + анализ + канальный ввод-вывод pv работает как минимум так же быстро, как файловый ввод-вывод + конвейерный ввод-вывод cat, поэтому pv вполне может не оказывать какого-либо отрицательного воздействия на стену. время выполнения всего конвейера.

Если это ожидаемое поведение, я только что наткнулся на очень простой способ увеличить скорость обработки на 10%.

Это объяснимое поведение, но не априорно ожидаемое поведение. Наблюдаемое вами ускорение, вероятно, будет зависеть от системы, данных, местоположения данных и других факторов. Вероятно, вы можете рассчитывать на дешевизну вставки pv в конвейер в большинстве случаев, но вы не можете разумно полагаться на это для общего улучшения производительности.

Я предполагаю, что pv не имеет отношения к этому и что cat .. | cat | zcat будет иметь аналогичное преимущество, просто разрешив опережающее чтение другого буфера канала.

that other guy 30.08.2024 23:27

Это был бы интересный эксперимент, @thatotherguy. Вы можете быть правы.

John Bollinger 30.08.2024 23:36

@thatotherguy Думаю, ты прав. cat .. | cat | zcat по сути имел ту же скорость, что и cat .. | pv | zcat. Ради любопытства я тоже протестировал его на крайнем случае cat .. | cat | cat | cat | zcat и он оказался примерно таким же, как cat .. | cat | zcat , так что благо хватило только на две трубки. Я поигрался с несколькими другими вариантами и увидел улучшение только тогда, когда в конечном итоге использовал zcat, так что, вероятно, это что-то уникальное для буферизации. Об этом стоит помнить, поскольку может оказаться полезным повысить производительность для больших заархивированных файлов.

apprentice iron chef 31.08.2024 00:04

Другие вопросы по теме