why-is-this-slow — コマンド実行の遅延解析CLI

Tool

概要

why-is-this-slow は、任意のコマンドを実行してその実行時間とリソース使用に関する「事実」を記録し、後から説明(explain)や比較(compare)できるように保存する軽量なGo製CLIです。繰り返し実行して中央値などの安定指標を取るリピートモード、子プロセスのCPU時間(user+sys)や最大RSS(rusageが利用可能な環境で)を取得する機能を持ちます。収集した各ランはOSに合わせた状態ディレクトリに保存され、後で履歴を参照して原因候補を絞ったり、パフォーマンスの回帰を検出したりする用途に適しています。プロファイラやトレーサとは異なり、関数単位やシステムコール単位の詳細な内訳は提供しませんが、手軽に状況を把握する「軽量計測器」として有用です。

GitHub

リポジトリの統計情報

  • スター数: 4
  • フォーク数: 3
  • ウォッチャー数: 4
  • コミット数: 4
  • ファイル数: 5
  • メインの言語: Go

主な特徴

  • 任意コマンドを実行して壁時計時間・子プロセスCPU時間・最大RSSなどを取得して記録
  • リピートモードで複数回実行し、安定した中央値などの指標を算出
  • 実行ごとの結果をOS適切な状態ディレクトリに保存し、後で explain / compare が可能
  • プロファイラではなく軽量な計測ツールとして設計(詳細な関数単位解析は行わない)

技術的なポイント

why-is-this-slow は小さくシンプルなGo製CLIとして設計されており、実行のオーケストレーション、統計集計、永続化に注力しています。コマンドの起動には標準ライブラリを用い、プロセスの開始から終了までの壁時計(実時間)を計測する一方、利用可能なプラットフォームでは rusage を利用して子プロセスの CPU 時間(ユーザ時間 + システム時間)と最大RSS(resident set size)を取得します。これにより、単純な経過時間だけでなく CPU バウンドかメモリ消費が原因か、といった切り分けに役立つ指標を得られます。

繰り返し実行する「リピートモード」は、単発実行のばらつきを排除するための実用的な工夫です。複数回のランから中央値などの代表値を採ることでノイズを減らし、安定した比較基準を提供します。各実行結果はコマンド文字列、引数、タイムスタンプ、計測値(wall, cpu,user+sys, maxrss など)を含むメタ情報として OS に適した状態ディレクトリ(例: XDG ベースやプラットフォーム固有ディレクトリ)に保存され、後から explain(単一実行の説明)や compare(複数実行の差分比較)が可能です。

設計上のトレードオフとして、why-is-this-slow はプロファイラやトレーサのように関数単位・システムコール単位での内訳を提供しません。深掘りが必要な場合は perf、strace、dtrace 等のツールと組み合わせることが推奨されています。コードベースが小さい点(ファイル数が少ない)や internal パッケージの構成から、導入や拡張がしやすく、CI 内での回帰検出や日常のコマンド比較用途に向いています。

プロジェクトの構成

主要なファイルとディレクトリ:

  • .github: dir
  • .gitignore: file
  • README.md: file
  • go.mod: file
  • internal: dir

まとめ

手軽にコマンドの遅延原因候補を記録・比較できる、小さく実用的な計測CLI。

リポジトリ情報:

READMEの抜粋:

Why is this slow?

A small Go CLI that runs a command, records timing and resource facts, and keeps them so you can explain or compare later.

Details

  • What it is: lightweight timer with repeat mode for stable medians; captures child CPU (user+sys) time and max RSS via rusage when supported; stores every run under an OS-appropriate state directory for later explain and compare.
  • What it is not: a profiler or tracer; it will not pinpoint specific functions or syscalls. Use perf, strace, or…