**C におけるクロージャーのコスト ― 残り**

2025/12/31 16:44

**C におけるクロージャーのコスト ― 残り**

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

(完全な詳細を含めるために補完された内容):**

改訂要約

この記事は、2020年のMacBook Pro M1(Apple Clang 17およびGCC 15)上でMan‑or‑Boyテストを用いて、さまざまなC/C++クロージャ技術をベンチマークしています。各バリアントは150回実行され、100,000以上のイテレーションで壁時計時間とCPU時間の両方が測定されています。

新しい「Plain C」カテゴリが追加されました:

  • 通常関数(コンテキストなし)– 最速のベースライン。
  • 通常関数(Rosetta Code) – 間接的な
    int* k
    ポインタを含む;プレーン版より遅い。
  • 通常関数(Static) – コンテキストに静的変数を使用;スレッドセーフではない。
  • 通常関数(Thread Local) – 静的を
    thread_local
    で置き換える;スレッドセーフだが追加のロード/ストアオーバーヘッドが発生。

結果は、通常関数から間接ポインタを除去するとRosetta‑Codeバージョンより明確に高速化されることを示しています。ラムダは型情報が保持されたままでは最速であり、任意の型消去(例:

std::function
std::function_ref
)は測定可能なオーバーヘッドを追加します。静的およびスレッドローカルアプローチは、追加のロード/ストアコストによりプレーン関数シグネチャより遅くなります。GNU Nested Functionsはパフォーマンスが低下し、静的/スレッドローカル変種と同等またはそれ以下である一方、Apple Blocksもラムダに比べて顕著なオーバーヘッドを示します。

この記事の結論として、ISO‑C「Capture Functions」(標準で提案されたもの)およびワイド関数ポインタが既存の拡張機能よりも優れた性能を提供できる可能性があるとし、将来の言語またはライブラリ更新への方向性を示唆しています。開発者にとっては、パフォーマンスクリティカルなコードではプレーン関数や型付きラムダを優先するべきであり、コンパイラおよびライブラリ作者は埋め込みシステム、ゲームエンジン、高頻度取引などの領域でオーバーヘッドを削減するためにCapture Functionsを採用できると結論付けています。


最終注記: 改訂要約はリストからすべての主要ポイントを完全に反映し、明確で分かりやすく、曖昧または混乱する表現がないことを確認しています。

本文

前回の記事では、C および C++ でのクロージャ実装を「性能」面から検証しました。
ただし、比較に有用な代表的手法の一部は抜けてしまっていました。
ベンチマークを少数の新カテゴリで再実行することで、
それら普及しているアプローチが他とどのように位置づけられるか定量化できます。


導入部分は省略

前回の記事に簡単な概要があります。
C/C++ で使われるクロージャの詳細を深く知りたい場合は、
古い記事または進行中の C 設計提案をご覧ください。
そこでは、これらの手法が「効率的」か「非効率的」になる技術的・設計上の理由を解説しています。

ここでの目的は依然として性能です:
さまざまな設計の特徴を推定すること。
既にカバーした内容は省き、ベンチマークへの新追加項目と主要結論に注力します。

すべてのベンチマーク実装は公開されています¹。


実験設定

前回との唯一の変更点は、100 000+ サンプルイテレーションを 150 回繰り返すことです(以前は 50〜100 回)。
詳細は記事末尾に記載しています。


Plain C – 新カテゴリ

新しいベンチマークカテゴリは「Plain C」アプローチを追跡します:

カテゴリ説明
Normal Functions追加引数でデータを渡す通常の C 関数(
qsort
qsort_r/qsort_s
に書き換えるのと同じ)。
Normal Functions (Rosetta Code)Rosetta Code の週刊例題から直接採用。再帰呼び出し時に既存の
k
値を参照するために
int* k
ポインタを使用。
Normal Functions (Static)静的変数で次関数へのコンテキストを渡す通常の C 関数。スレッド安全ではなく、呼び出し署名は変更されない。
Normal Functions (Thread Local)「Static」と同様だが
thread_local
変数を使用。スレッド安全で、まだ署名は変更されない。

「Normal Functions」とは微妙ですが重要な違いがあります。
2つのバリアントは関数署名を変更しませんので、

void* user_data
を持たない既存
qsort
API と互換性があります。FFI などで重要です。

例:不要引数を追加する場合

int f0(arg* unused) { (void)unused; return 0; }

元のインターフェースを保つ:

int f0() { return 0; }

この変更は性能にほとんど影響しないと思われがちですが、ベンチマークで異なる結果が出ました。


結果

差が無ければ報告すべきではありません。
「Normal Functions」各バリアントのコスト(あるいは無コスト)を他と比較した図は以下の通りです:

(図は省略 – 元記事参照)

一部解決策が極端に遅いため、線形グラフでは有用な詳細が隠れます。対数スケールで可視化すると誤差棒が読みにくくなります。最終的には「Lambda (Rosetta Code)」などの悪い外れ値を除去した後、線形スケールに戻してより明確にしています。


洞察

大幅改善:「Normal Functions (Rosetta Code)」→「Normal Functions」

主な変更は

int* k
ポインタを削除することです。
int k
を直接使用すると、1 レベルの間接参照が排除され、パフォーマンスが大きく向上します。

ラムダは依然リード

ラムダは追加構造なしに型情報を保持できるため、性能が優れています。
C++ ではテンプレートで再帰を境界化できますが、Plain C にはないのでマクロや間接参照を使わざるを得ません。コンパイラが完全に展開できなければ、そのコストは見えなくなります。

微小型の型消去

std::function_ref<int(void)>
のような最小限の型消去を追加すると、純粋ラムダよりも性能が低下します。静的・スレッドローカル変数は呼び出しごとにロード/ストアが必要でオーバーヘッドになります。

GNU ネスト関数

GNU のネスト関数はスタックベースのトランペリンを使用するため、現在の実装ではコストが高くなり、高性能コードには不向きです。Clang が実装しない決定はこの事実に合致します。


最終結論

  • ラムダ(または提案されたキャプチャ関数) は型情報が完全に保持される場合に最速です。
  • 型を保持したクロージャ + 可能な限り薄い型消去(ワイド関数ポインタ)は、既存の C 拡張や署名変更しない Plain C コードよりも即座に利益を得られます。
  • Apple BlocksGNU ネスト関数 は設計上の欠点があり、主流コンパイラへの統合は難しいです。
  • 将来の C エコシステムで「フレーム/環境」をポインタ経由で取得することは推奨されません。
  • 複雑なケースでは C プログラマは必然的に型消去による性能低下を受けます。マクロベースの汎用プログラミングが速度とコードサイズのトレードオフで対処可能です。

静的および

thread_local
バリアントは追加コストが大きく、特に GCC では顕著です。MSVC の数値も同様の傾向を示すでしょう。


方法論

テストは 13″ 2020 MacBook Pro M1 (16 GB RAM, macOS 15.7.2 Sequoia) 上で、AppleClang と Homebrew インストール GCC を使用。
ベンチマークは「Man‑or‑Boy」テストを採用し、

k
は共有オブジェクトから読み込むようにしてコンパイラ最適化による再帰の定数化を防止しています。

2 種類の測定(壁時計時間と CPU 時間)を行い、各ループは数千〜数十万回実行し平均値を取った後、150 回繰り返してバー高さを決定しました。
13 のカテゴリ(no‑op、normal functions、static/thread‑local バリアント、さまざまなラムダアプローチ、Apple Blocks、GNU Nested Functions、カスタム C++ クラス、shared_ptr)をベンチマーク。
誤差棒は 150 回の実行での標準誤差です。AppleClang 17 と GCC 15 をテストし、MSVC はこれら拡張機能が無いため除外しました。


Happy New Year, and until next performance deep‑dive! 💚

同じ日のほかのニュース

一覧に戻る →

2026/01/03 4:48

自分のサイトで公開し、他所ではシンジケート(転載)してください。

## Japanese Translation: --- ## 要約 POSSE(**Publish on Your Own Site, Syndicate Elsewhere**)は、作家がまず自分のサイトにコンテンツを投稿し、その後第三者のサイロへ複製することで、元のコピーを完全に管理したまま公開できる出版モデルです。主なメリットは、外部プラットフォームへの依存度低減、正規URLの所有権確保、検索性向上、シンジケートからのレスポンスを逆流させる能力、およびソーシャルレイヤーの活用です。すべて自己ホスト状態を犠牲にすることなく実現します。 POSSEは、パーマショートリンクや引用経由でシンジケートコピーからのバックリンクを奨励し、発見性を高め、スパム対策を行い、元記事のSEOを向上させます。モデルは完全なCRUD操作をサポートします:下流コピーをu‑syndicationリンクで読み取り、編集または再投稿で更新し、既存アクティビティを考慮して削除できます。 ### 実装パターン 1. **自動サーバー側シンジケーション**(クライアント → サイト → サイロ):新しいコンテンツが公開されると、サイトは自動的にサイロへ投稿します。 2. **クライアント → サイト + 手動サイロ投稿**:クライアントがローカルで公開し、その後選択したサイロへ手動で投稿します。この方法はより多くの制御を提供しますが、自動化は減少します。 ### 人気のあるサイロ Twitter、Facebook、Medium、WordPress.com、Flickr、Mastodon、Bluesky など。 ### POSSEを可能にするツール Bridgy Publish、SiloRider、Feed2Toot、POSSE Party などが挙げられます。 ### 関連概念 - **COPE**(Create Once, Publish Everywhere) - **POSE**(Publish Once Syndicate Everywhere) - **PESOS**(Post Elsewhere, Syndicate to Own Site) - **PESETAS**(post to a single silo only) ### 歴史的マイルストーン Tantek Çelik が 2010 年に POSSE を定義し、2012 年に正式化しました。それ以来、Barnaby Walters、Aaron Parecki、Ben Werdmuller、Shane Becker、および Molly White といった IndieWeb 実践者がさまざまな CMS やカスタムセットアップで導入しています。エコシステムは 2024 年までに新しいツールとデプロイメントを通じて着実に成長しました。 ### 今後の展望 本文では、POSSE ユーティリティの継続的な拡張と多様な「サイロ」への広範な採用が予測されています。さらに非ウェブ領域(例:git リポジトリのミラーリング)まで拡大する可能性があります。このシフトは、個人クリエイターや小規模ビジネスに力を与え、支配的プラットフォームへの依存を減らしつつ SEO とオーディエンス エンゲージメントを向上させることが期待されます。

2026/01/03 13:01

**IQuest‑Coder:Claude Sonnet 4.5 および GPT 5.1 を凌駕する新しいオープンソースコードモデル**

## Japanese Translation: --- ### Summary GitHubは、Copilotとその拡張AIツールキット(Spark、Models、MCP Registry)でコードを書き、Actions、Codespaces、Issues、Code Review、および自動ワークフローパイプラインを通じてアプリケーションのデプロイ、監視、セキュリティを行うという、ソフトウェア開発のすべての段階をスムーズにする完全統合型AI搭載開発者プラットフォームとして自社を位置付けています。 このプラットフォームは、GitHub Advanced Security の脆弱性スキャンとシークレット保護という高度なセキュリティ機能を、CI/CD ライフサイクル全体にわたるオートメーションツールと統合しています。ターゲットユーザーは、企業、中小規模チーム、スタートアップ、非営利団体、およびアプリモダニゼーション、DevSecOps、DevOps、継続的インテグレーション/デプロイメントなどの専門ユースケースを含む広範なスペクトルです。 明示的に対応する産業にはヘルスケア、金融サービス、製造業、および政府があり、それぞれのセクター向けにカスタマイズされたソリューションが提供されています。 GitHub の戦略は、プロンプト管理やインテリジェントなアプリデプロイメントなどAI統合を深化させるとともに、エンタープライズグレードのセキュリティ機能、Copilot for Business、プレミアム24/7サポート、および追加オプションの拡充を図っています。これらの動きはコーディングワークフローの高速化、コンプライアンス制御の強化、およびプラットフォーム全体の魅力拡大を目指しています。 コミュニティエンゲージメントは、Security Lab、Maintainer Community、Accelerator、Archive Program、GitHub Sponsors プログラムなどのイニシアチブを通じて強化され、オープンソース開発者を支援し、ソフトウェア業界全体での協力を促進します。ドキュメント、ブログ、変更履歴、マーケットプレイス、コミュニティフォーラム、およびパートナープログラムは、ユーザーが開発ジャーニーを通じて継続的にサポートされるようにさらに支援しています。 ---

2026/01/03 6:27

「『Harder, Better, Faster, Stronger』のBPMに合わせたダフトパンクのイースターエッグはありますか?」

## Japanese Translation: ## 改訂要約 Daft Punk の「Harder, Better, Faster, Stronger」は一般的に 123 BPM としてリストされていますが、正確な分析では実際のテンポは **123.45 BPM** であることが示されました。この微妙さは標準の一覧では見落とされがちです。 著者はリアルタイム BPM 検出アプリ「Tempi」を構築し、数百曲のサニペットライブラリでテストしました。Tempo アプリを使って手動でテンポを測定し、最初の明確なビート(約 5.58 秒)と最後のビート(約 3:41.85 秒)の間にある全ビート数をカウントし、式 `bpm = 60 * (number_of_beats‑1) / duration` を適用しました。Discovery CD のリップでは **123.44994 BPM** が得られ、YouTube バージョンでは **123.45336 BPM** でした。両方とも四捨五入すると **123.45 BPM** に一致します。CD バージョンは処理が少ないため、より代表的と考えられます。 著者は FFT(高速フーリエ変換)や自己相関に依存するアルゴリズムベースのテンポ検出ツールはノイズが多く不正確である可能性を指摘し、手動測定の方がより信頼できる数値を提供すると述べています。 Daft Punk の機材—E‑mu SP‑1200、Akai MPC‑3000、および Emagic Logic—は BPM を異なる小数点精度でサポートしています(前二つでは一桁、Logic では最大四桁)。2001 年と 2013 年のインタビューでは、これらのデバイスでシーケンスを行い、コンピュータを使わないという主張があり、制作時に分数 BPM が可能だったことを示唆しています。 結論として、正確な **123.45 BPM** は Daft Punk の「ロボット的」プロダクションプロセスによる意図的なイースターエッグであると考えられます。このような隠された詳細を認識することは、音楽テック開発者、DJ、および作品に微妙な参照を埋め込むアーティストに有益です。