Как я могу узнать производительность git?
Как администратор Devops, как можно проверить производительность git в моей среде?
После каждого серьезного изменения, такого как обновление Git, я хочу запустить тест, который узнает, как работает мой git.
Как мне этого добиться?
4 ответа
Ответ 2022 года заключается в использованииavar/git-hyperfine/
, обертка вокругsharkdp/hyperfine
, инструмент сравнительного анализа командной строки.
Иллюстрация:
Git 2.38 (3 квартал 2022 г.) позволяет передавать большие объекты, считанные из потока пакетов, в свободный объектный файл напрямую, без необходимости хранить его в ядре целиком.
Улучшение производительности измеряется с помощью .
См. , коммит 2b6070a, коммит 97a9db6, коммит a1bf5ca (11 июня 2022 г.) Хан Син (
chiyutianyi
).
См. коммит 3c3ca0b, коммит 21e7d88 (11 июня 2022 г.) от Ævar Arnfjörð Bjarmason (
avar
).
(Объединено Junio C Hamano --
gitster
-- в коммите 73b9ef6, 14 июля 2022 г.)
коммит aaf8122
unpack-objects
: используйте для распаковки больших объектовПомощь: Эвар Арнфьорд Бьярмасон
Помощь: Деррик Столи
Помощь: Цзян Синь
Подпись: Хань Синь
Подпись: Эвар Арнфьорд Бьярмасон
Используйте
stream_loose_object()
введенная в предыдущем коммите функция для распаковки больших объектов.
До этого нам нужно было бы malloc() размер BLOB-объекта перед его распаковкой, что могло привести к OOM с очень большими BLOB-объектами.Мы могли бы использовать новый потоковый интерфейс для распаковки всех больших двоичных объектов, но это было бы намного медленнее, как показано, например, в этом тесте с использованием
git-hyperfine
:rm -rf /tmp/scalar.git && git clone --bare https://github.com/Microsoft/scalar.git /tmp/scalar.git && mv /tmp/scalar.git/objects/pack/*.pack /tmp/scalar.git/my.pack && git hyperfine \ -r 2 --warmup 1 \ -L rev origin/master,HEAD -L v "10,512,1k,1m" \ -s 'make' \ -p 'git init --bare dest.git' \ -c 'rm -rf dest.git' \ './git -C dest.git -c core.bigFileThreshold={v} unpack-objects </tmp/scalar.git/my.pack'
Здесь мы будем работать хуже с более низкими настройками с этим изменением скорости, но взамен мы получим меньшее использование памяти:
Summary './git -C dest.git -c core.bigFileThreshold=10 unpack-objects </tmp/scalar.git/my.pack' in 'origin/master' ran 1.01 ± 0.01 times faster than './git -C dest.git -c core.bigFileThreshold=1k unpack-objects </tmp/scalar.git/my.pack' in 'origin/master' 1.01 ± 0.01 times faster than './git -C dest.git -c core.bigFileThreshold=1m unpack-objects </tmp/scalar.git/my.pack' in 'origin/master' 1.01 ± 0.02 times faster than './git -C dest.git -c core.bigFileThreshold=1m unpack-objects </tmp/scalar.git/my.pack' in 'HEAD' 1.02 ± 0.00 times faster than './git -C dest.git -c core.bigFileThreshold=512 unpack-objects </tmp/scalar.git/my.pack' in 'origin/master' 1.09 ± 0.01 times faster than './git -C dest.git -c core.bigFileThreshold=1k unpack-objects </tmp/scalar.git/my.pack' in 'HEAD' 1.10 ± 0.00 times faster than './git -C dest.git -c core.bigFileThreshold=512 unpack-objects </tmp/scalar.git/my.pack' in 'HEAD' 1.11 ± 0.00 times faster than './git -C dest.git -c core.bigFileThreshold=10 unpack-objects </tmp/scalar.git/my.pack' in 'HEAD'
Лучший тест для демонстрации преимуществ этого, который создает искусственное репо с большим двоичным объектом размером 1, 25, 50, 75 и 100 МБ:
rm -rf /tmp/repo && git init /tmp/repo && ( cd /tmp/repo && for i in 1 25 50 75 100 do dd if=/dev/urandom of=blob.$i count=$(($i*1024)) bs=1024 done && git add blob.* && git commit -mblobs && git gc && PACK=$(echo .git/objects/pack/pack-*.pack) && cp "$PACK" my.pack ) && git hyperfine \ --show-output \ -L rev origin/master,HEAD -L v "512,50m,100m" \ -s 'make' \ -p 'git init --bare dest.git' \ -c 'rm -rf dest.git' \ '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold={v} unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum'
Используя этот тест, мы всегда будем использовать> 100 МБ памяти на
origin/master
(около ~105 МБ), но максимум, например, ~55 МБ, если мы установимcore.bigFileThreshold=50m
.Соответствующие строки «Максимальный размер резидентного набора» были добавлены вручную ниже соответствующего эталона:
'/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=50m unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'origin/master' ran Maximum resident set size (kbytes): 107080 1.02 ± 0.78 times faster than '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=512 unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'origin/master' Maximum resident set size (kbytes): 106968 1.09 ± 0.79 times faster than '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=100m unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'origin/master' Maximum resident set size (kbytes): 107032 1.42 ± 1.07 times faster than '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=100m unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'HEAD' Maximum resident set size (kbytes): 107072 1.83 ± 1.02 times faster than '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=50m unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'HEAD' Maximum resident set size (kbytes): 55704 2.16 ± 1.19 times faster than '/usr/bin/time -v ./git -C dest.git -c core.bigFileThreshold=512 unpack-objects </tmp/repo/my.pack 2>&1 | grep Maximum' in 'HEAD' Maximum resident set size (kbytes): 4564
Это показывает, что если у вас достаточно памяти, этот новый метод потоковой передачи работает медленнее, чем ниже вы устанавливаете порог потоковой передачи, но преимущество заключается в более ограниченном использовании памяти.
В более ранней версии этого патча появился новый "
core.bigFileStreamingThreshold
"вместо повторного использования существующей переменной "" .
Как отмечено в подробном обзоре ее пользователей в этой ветке , ее использование имеет несколько разных значений.Тем не менее, мы считаем, что достаточно просто повторно использовать его.
Хотя возможно, что кто-то захочет, например, считать объекты «маленькими» для целей сравнения, но «большими» для целей их написания, такие варианты использования, вероятно, слишком неясны, чтобы о них беспокоиться.
Мы всегда можем расстаться»core.bigFileThreshold
«В будущем, если в этом возникнет необходимость.
Да, как указал @DevidN, это зависит от различных параметров, таких как конфигурация, Сеть. У меня также был такой же Q, когда мы мигрировали из SVN в git и stats после миграции.
Я использовал "время" с комбинацией различных команд git и написал скрипт для мониторинга всех этих команд с сервера.
Например:
$ time git clone http://####@#########.git
Cloning into '#####'...
remote: Counting objects: 849, done.
remote: Compressing objects: 100% (585/585), done.
remote: Total 849 (delta 435), reused 0 (delta 0)
Receiving objects: 100% (849/849), 120.85 KiB | 0 bytes/s, done.
Resolving deltas: 100% (435/435), done.
Checking connectivity... done.
real 0m4.895s
user 0m0.140s
sys 0m0.046s
Покаgit-hyperfine
выглядит интересно, у меня сложилось впечатление, что это в основном инструмент для разработчиков git. Как пользователь, я думаю, что проще придерживаться ванили.hyperfine
. Например
$ hyperfine --warmup 3 -L rev /usr/bin/git,/opt/homebrew/Cellar/git/2.42.0/bin/git '{rev} status'
Benchmark 1: /usr/bin/git status
Time (mean ± σ): 87.3 ms ± 1.9 ms [User: 32.1 ms, System: 327.4 ms]
Range (min … max): 84.9 ms … 93.7 ms 32 runs
Benchmark 2: /opt/homebrew/Cellar/git/2.42.0/bin/git status
Time (mean ± σ): 76.0 ms ± 3.6 ms [User: 28.9 ms, System: 301.0 ms]
Range (min … max): 72.7 ms … 94.7 ms 38 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
Summary
/opt/homebrew/Cellar/git/2.42.0/bin/git status ran
1.15 ± 0.06 times faster than /usr/bin/git status
Главное — использовать реальный инструмент сравнительного анализа, а неtime
который не дает стандартных отклонений и, следовательно, не дает сопоставимых результатов, если разница не огромна.
Что касается используемых тестовых примеров: боюсь, вы сами это решаете, поскольку это сильно зависит от ваших вариантов использования и репозиториев.
Другой способ проверить производительность Git - использовать не очень старую папку perf: "Структура тестирования производительности", представленная в 2012 году с Git 1.7.10, с коммитом 342e9ef.
- скрипт run позволяет вам указать произвольные каталоги и ревизии сборки.
- Это позволяет вам указать, какие тесты запускать; или вы также можете сделать это вручную
- Можно настроить два разных размера тестовых репозиториев, и сценарии просто скопируют один или несколько из них.
Так... make perf
Git 2.14 (3-й квартал 2017 года) все еще добавляет к этой платформе тест, показывающий, что время выполнения wildmatch()
Функция, используемая для сгущения при мерзости, растет в геометрической прогрессии перед лицом некоторых патологических шаров.
См. Коммит 62ca75a, коммит 91de27c (11 мая 2017 г.) Ævar Arnfjörð Bjarmason ( avar
)
(Объединено Юнио С Хамано - gitster
- в коммите 140921c, 30 мая 2017 г.)