5月11日、Linux向けオープンソースプロジェクトEta Labsが「Comparison of C/POSIX standard library implementations for Linux」と題した記事を公開した。この記事では、LinuxにおけるC/POSIX標準ライブラリの実装の比較について詳しく紹介されている。

このページは、Linux上で利用可能なさまざまな標準ライブラリの実装を比較したものである。著者は比較対象の一つであるmuslの開発者であり、比較対象の選別や結果に偏りが生じている可能性があるが、筆者自身もそれを認めていることから、一定の公平性は保たれていると言えるだろう。今後、この比較には詳細なパフォーマンスベンチマークと、GoogleのBionicや他のBSD libcポートなど、さらなるライブラリの実装が追加される予定である。
以下に、その内容を抜粋して紹介する。詳細な内容については原文を参照していただきたい。
ライブラリ利用時のファイルサイズ比較
以下の表では、musl、uClibc、dietlibc、glibcの4つのライブラリに関して、各種ファイルセットのサイズや静的および動的オーバーヘッドを比較している。いずれも、muslが良好な結果を示している。
ファイルサイズの膨張度合い比較 | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
完全な.aセット | 426k | 500k | 120k | 2.0M † |
完全な.soセット | 527k | 560k | 185k | 7.9M † |
最小の静的Cプログラム | 1.8k | 5k | 0.2k | 662k |
静的hello(printf使用) | 13k | 70k | 6k | 662k |
動的オーバーヘッド(最小のダーティ) | 20k | 40k | 40k | 48k |
静的オーバーヘッド(最小のダーティ) | 8k | 12k | 8k | 28k |
静的stdioオーバーヘッド(最小のダーティ) | 8k | 24k | 16k | 36k |
設定可能な機能セット | no | yes | 最小限 | 最小限 |
リソース枯渇時の挙動
リソースが極端に少ない場合における挙動の比較では、各ライブラリのリソース不足時の処理が示されている。以下の表では、リソース枯渇時の挙動をまとめている。
リソース枯渇時の挙動 | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
スレッドローカルストレージ | 失敗報告 | 異常終了 | 対応なし | 異常終了 |
SIGEV_THREADタイマー | 失敗なし | 対応なし | 対応なし | オーバーランを失う |
pthread_cancel | 失敗なし | 異常終了 | 対応なし | 異常終了 |
regcompとregexec | 失敗報告 | クラッシュ | 失敗報告 | クラッシュ |
fnmatch | 失敗なし | 不明 | 失敗なし | 失敗報告 |
printfファミリー | 失敗なし | 失敗なし | 失敗なし | 失敗報告 |
strtolファミリー | 失敗なし | 失敗なし | class="best"失敗なし | 失敗なし |
パフォーマンス比較
以下の表は、各ライブラリのパフォーマンスを測定した結果を示している。特に、muslは小規模なメモリアロケーションの処理が非常に高速である一方、glibcは最も遅いことがわかる。
パフォーマンス比較 | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
小規模メモリアロケーション | 0.005 | 0.004 | 0.013 | 0.002 |
大規模メモリアロケーション | 0.027 | 0.018 | 0.023 | 0.016 |
メモリアロケーションの競合(ローカル) | 0.048 | 0.134 | 0.393 | 0.041 |
メモリアロケーションの競合(共有) | 0.050 | 0.132 | 0.394 | 0.062 |
ゼロフィル(memset) | 0.023 | 0.048 | 0.055 | 0.012 |
文字列長(strlen) | 0.081 | 0.098 | 0.161 | 0.048 |
バイト検索(strchr) | 0.142 | 0.243 | 0.198 | 0.028 |
部分文字列(strstr) | 0.057 | 1.273 | 1.030 | 0.088 |
スレッド作成・結合 | 0.248 | 0.126 | 45.761 | 0.142 |
ミューテックスロック/アンロック | 0.042 | 0.055 | 0.785 | 0.046 |
UTF-8デコード(buffered) | 0.073 | 0.140 | 0.257 | 0.351 |
UTF-8デコード(byte-by-byte) | 0.153 | 0.395 | 0.236 | 0.563 |
Stdio putc/getc | 0.270 | 0.808 | 7.791 | 0.497 |
Stdio putc/getc ロックなし | 0.200 | 0.282 | 0.269 | 0.144 |
正規表現のコンパイル | 0.058 | 0.041 | 0.014 | 0.039 |
正規表現の検索(a{25}b) | 0.188 | 0.188 | 0.967 | 0.137 |
Self-exec(静的リンク) | 234µs | 245µs | 272µs | 457µs |
Self-exec(動的リンク) | 446µs | 590µs | 675µs | 864µs |
ABIおよびバージョニングの比較
ABIおよびバージョニングに関する比較では、muslが最も安定したABIを提供しており、古いバージョンのライブラリとの互換性を維持しつつ、前方互換性も確保している。一方で、glibcはバージョン管理に関して問題が多く、互換性に課題がある。
ABIおよびバージョニング比較 | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
安定したABI | はい | いいえ | 非公式 | はい |
LSB互換ABI | 不完全 | いいえ | いいえ | はい |
後方互換性 | はい | いいえ | 非公式 | はい |
前方互換性 | はい | いいえ | 非公式 | いいえ |
原子単位でのアップグレード | はい | いいえ | いいえ | いいえ |
シンボルバージョニング | いいえ | いいえ | いいえ | はい |
セキュリティ/ハードニング比較
セキュリティおよびハードニングについては、muslがリソースを効率的に使用し、過剰なメモリ消費を避けつつ、堅牢なセキュリティを提供していることが強調されている。glibcはセキュリティに過剰に対応し、メモリ消費が多くなる傾向がある。
セキュリティ/ハードニング比較 | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
角ケースへの対応 | はい | はい | いいえ | 過剰なmalloc使用 |
安全なUTF-8デコーダー | はい | はい | いいえ | はい |
超線形の大きさの回避 | はい | 時々 | いいえ | はい |
スタック破壊保護 | はい | はい | いいえ | はい |
ヒープ破損検出 | はい | いいえ | いいえ | はい |
完全な一覧はComparison of C/POSIX standard library implementations for Linuxを参照していただきたい。