この記事は KLab Engineer Advent Calendar 2018 の6日目のエントリです。
最近のmacOSでは新しいファイルシステムが採用されていて、ファイルコピーが一瞬でできますよ、性能改善やストレージの空き容量を増やすのに役立つかもしれませんよ、という話を紹介します。
最近のmacOSのファイルシステム:APFS
まず最近のMacのファイルシステムについて紹介します。2017年9月リリースのmacOS 10.13 (High Sierra) 以降、macOSでは標準のファイルシステムとしてAPFS (Apple File System) が採用されています。これはコピーオンライトファイルシステムというジャンルに属するもので、同じファイルを作成する際に実体を共有して、どちらか一方が更新された時に初めてファイルコピーを行うような仕組みを持つ、モダンなファイルシステムです。同様のファイルシステムとしてはZFSやBtrfsが挙げられます。
APFS上で実体を共有したファイルコピーを行う
そんな特徴を持ったAPFSですが、単にcpコマンドでファイルコピーをしても従来通りに別の実体を作ってしまい、APFSのメリットは生かせません。実はmac OS 10.13以降、標準のcpコマンドにAPFSのためのオプションが一つ追加されています。
$ man cp
(略)
-c copy files using clonefile(2)
cpコマンドに -c
オプションをつけると clonefile
システムコールを使ってコピーしてくれるんだそうです。これはまさに我々が求めている、実体を共有した形でのコピーです。
これを使ってコピーを行うと、ファイルのコピーは一瞬で終わります。約300MBのファイルをコピーしてみましょう。
$ /usr/bin/time cp -c pycharm-community-2018.3.dmg f1
0.00 real 0.00 user 0.00 sys
$ /usr/bin/time cp -c pycharm-community-2018.3.dmg f2
0.00 real 0.00 user 0.00 sys
$ /usr/bin/time cp pycharm-community-2018.3.dmg f3
1.60 real 0.00 user 0.29 sys
$ /usr/bin/time cp pycharm-community-2018.3.dmg f4
0.96 real 0.00 user 0.23 sys
-c
オプション付きで2回、 -c
オプションなしで2回、ファイルのコピーを行ってみました。前者は0.01秒未満で実行終了しているのに対し、後者は約1秒から1.5秒ほどかかっています。どうやら2桁くらい速度が違いそうですね1。
また、df
コマンドでディスクの空き容量を観察していると、 cp -c
では空き容量が1バイトも減りませんでした。コピーが速くてストレージ容量も消費しないということですから、いいことづくめですね。
cp -cの利用シーン
さて、この cp -c
による速いコピーは何に使えるでしょうか。
まず、バイナリビルドやアセットビルドの際にファイルコピーがボトルネックになっているような部分があれば、コピーをcp -c
に変更することで性能改善になる可能性があります。
また、UnityプロジェクトだとSwitch Platformを避けるため同一プロジェクトのコピーを複数持つようなことをされている方も多いかと思います。このような場合に、ワーキングコピー全体を cp -cr
でコピーすればストレージにはずいぶん優しくなるはずです。
存在する重複ファイルを検出し、cp -c
によって実体を共有することでディスク容量を削減することもできるでしょう。すでにそのような試みも行われています2。
まとめ
- 最近のmacOSではAPFSというファイルシステムが採用されている
- APFSでは
cp -c
でファイルの実体を共有したコピーが実現できる- 実体を共有したファイルのどれか1つが変更されると、そのタイミングで初めてファイルコピーが行われる
-
cp -c
を利用すれば性能改善やディスク空き容量増加などのメリットが得られるのでは
ハードリンクを使えば同様のディスク容量削減は実現できるのですが、ハードリンクだと編集する際に注意しないと全ファイルを書き換えてしまって事故につながる可能性があります。ファイルシステムの機能で「安全なハードリンク」を実現できるのは嬉しいですね。
APFSはまだ登場から歴史が浅いので、全面的に信用していいかどうか判断が難しいところかもしれません。とはいえ魅力的な機能を提供しているように思いますので、使えるところでは積極的に使っていきたいと個人的には考えています。
-
我が家の古いMacBookAirで実験しているので、読者の皆さんの手元ではもう少し違う結果になるかもしれません。 ↩
-
例えば https://github.com/ranvel/clonefile-dedup 。これ自体は利用者も多くなさそうなので、もう少し定評のあるツールが
clonefile(2)
をサポートしてくれればそれが一番良さそうです。 ↩