gitにでかいバイナリファイルを入れるとどうなるか

ふと気になったのでgitにでかいバイナリファイルを入れたらどうなるのか調べてみた。

自分の発表が録画された112メガのaviファイルを実験対象に使う。

cp

まずはgitを使わない普通のcpの時間を測っておく。

real    0m0.744s
user    0m0.001s
sys     0m0.179s

git add

git addにはコピーの10倍以上の時間がかかる。

real    0m9.339s
user    0m7.989s
sys     0m0.490s

git commit

git commitには意外と時間が掛からなかった。

real    0m0.055s
user    0m0.002s
sys     0m0.031s

git clone

先ほど動画ファイルをcommitしたリポジトリをcloneしてみる。単純なファイルコピーに比べると3倍弱時間がかかる。

real    0m1.943s
user    0m0.932s
sys     0m0.433s

git addには3パターンある

コミット済みのものを変更せずにそのままもう一度addした場合、きっとタイムスタンプを見てすぐに「変更されていない」と判断している。

real    0m0.020s
user    0m0.001s
sys     0m0.004s

タイムスタンプを変えるためにtouchしてからaddしてみた。それでも最初に追加した時ほどの時間は掛からない。何で判断しているのかな?

real    0m0.616s
user    0m0.507s
sys     0m0.094s

もちろんcatの追記でちょこっとファイル内容を変更してやると、初回add時と同じくらいの時間がかかる。

real    0m9.159s
user    0m7.994s
sys     0m0.490s

追記: time md5 ...ってしたらreal 0m0.617sだったので、2番目の例ではだいたいそれに類する処理が走っているんだと思われる。ということはむしろ3番目の例でこんなに時間がかかっているのが不思議なのか。バイナリーファイルかどうかとか無関係に差分を計算しているのかな?

さらに追記: 初回にaddしたときも同程度の時間がかかってるんだから差分計算じゃないよね、という指摘があったが全くそのとおり。んー、じゃあzlibでの圧縮に時間がかかっている?というわけで試しにtime zip ... ってやってみたら real 0m9.792s だった。なるほど、つまりは圧縮に時間がかかっている、と。

まとめ

細かい数値は記憶に残らないのであえてバッサリ要約すると、1GBのファイルがコピーに7秒掛かる環境で、同じファイルがaddに80秒、cloneに20秒掛かる、という比率。addにかかっている時間は大部分がzlibで圧縮するのに掛かる時間。ネットワーク越しcloneなどは計測していない。ファイルサイズを変えての計測も試してない。