拙作 gorak/errs パッケージの性能評価をしてもらった
こんなマイナーなパッケージの性能評価をしていただいてありがとうございます 🙇 いや,マジで。
pkg/errors
は昔から人気の高いエラーハンドリング・パッケージで,私も随分お世話になった。
このパッケージの更新が止まって read-only になったのに伴い代替となるパッケージが望まれていたのは知っている。
で,登場したのが cockroachdb/errors
パッケージなわけだ。
cockroachdb/errors
パッケージは,おそらく CockroachDB などのデータベース操作に向いたエラーハンドリング・パッケージと思われ, pkg/errors
との互換性を維持したまま PII (Personally Identifiable Information) のマスキングもできる優れものである。
pkg/errors
からの乗り換えを考えるなら cockroachdb/errors
パッケージはアリな選択だと思うし個人的にもお勧めである。
一方で拙作の goark/errs
はもう少し違うところを目指していて
- 任意の
error
インスタンスをラッピングすることに主眼を置く- 任意の error インスタンスを原因エラーとして埋め込み可能
- 任意のコンテキスト情報を埋め込み可能
- 既定でエラーが発生した関数名をコンテキスト情報として保持する
- 構造化されたエラー情報を JSON 形式で出力可能
- MarshalJSON() メソッド完備
- 書式
%+v
を使って JSON 形式で出力 - 任意の
error
インスタンスで(Unwrap
メソッドの挙動に従い)可能な限り構造を辿って出力
といった機能を有している。
もちろんこれは pkg/errors
パッケージに対するささやかな不満から来ている。
私は「スタック情報は9割以上がノイズ」「藁束の中から金の針を探すようなもの」という危険思想の持ち主なので,どういう形であれスタック情報を丸ごとどーんと出力することはしないようにしている。 他人様が書いた Java コードのデバッグでカジュアルにスタックトレースを吐き出しやがる(しかもそれを見ても結局分からずデバッガを動かす羽目になる)のに辟易してたというのもある。
それならスタック情報はエラーを吐き出した関数名を保持するのみとし,あとはエラーに至る「文脈(context)」をできる限りかき集めてエラー・インスタンスに突っ込むという戦略のほうが幾らかマシだろう,と考えたのだ。 どうしても関数呼び出しの構造が欲しければ,エラーを検出した時点で都度ラッピングしていけばいいという考え方である。
ところで最初に挙げた記事では
と評価をいただいていて, JSON の marshalling については(一瞬心が揺らいだが)性能がよくてもサードパーティのパッケージには依存したくないというのがあるので,パスさせていただくが, fmt
.Sprintf
に関しては正直に言って実装をサボっているだけなので,少し改善してみることにした。
まずは miyataka/benchmark_pkg_errors_alternatives を拝借して改めてベンチマークをとってみる。
他のパッケージと比べても仕方がないので goark/errs
を使った結果のみ示すと
benchmark | ns/op | B/op | allocs/op |
---|---|---|---|
BenchmarkErrors/goark/errs-stack-10-12 | 2746 | 648 | 7 |
BenchmarkErrors/goark/errs-stack-100-12 | 3278 | 648 | 7 |
BenchmarkErrors/goark/errs-stack-1000-12 | 6810 | 648 | 7 |
BenchmarkStackFormatting/goark/errs-%s-stack-10-12 | 167.3 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-10-12 | 185.0 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-10-12 | 8680 | 1401 | 33 |
BenchmarkStackFormatting/goark/errs-%s-stack-30-12 | 174.8 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-30-12 | 180.4 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-30-12 | 8826 | 1401 | 33 |
BenchmarkStackFormatting/goark/errs-%s-stack-60-12 | 170.0 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-60-12 | 160.5 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-60-12 | 8636 | 1401 | 33 |
うっ,アロケート回数が33回とか orz
凹みつつも JSON データ生成部分でなるべく fmt
.Sprintf
を使わないようにした v1.2.3 をリリースした。
これを使って同じ条件でベンチマークをとってみたのだが
benchmark | ns/op | B/op | allocs/op |
---|---|---|---|
BenchmarkErrors/goark/errs-stack-10-12 | 2850 | 648 | 7 |
BenchmarkErrors/goark/errs-stack-100-12 | 3344 | 648 | 7 |
BenchmarkErrors/goark/errs-stack-1000-12 | 6365 | 648 | 7 |
BenchmarkStackFormatting/goark/errs-%s-stack-10-12 | 167.7 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-10-12 | 164.6 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-10-12 | 7098 | 1385 | 31 |
BenchmarkStackFormatting/goark/errs-%s-stack-30-12 | 171.8 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-30-12 | 171.5 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-30-12 | 6974 | 1385 | 31 |
BenchmarkStackFormatting/goark/errs-%s-stack-60-12 | 173.9 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%v-stack-60-12 | 164.8 | 8 | 1 |
BenchmarkStackFormatting/goark/errs-%+v-stack-60-12 | 7097 | 1385 | 31 |
ちょっとしか変わらん orz
やっぱ json
.Marshal
を使ってるのがあかんのか? そもそも改善になってない?
…というわけで諦めました。 こんなのでよろしければ使ってやってください。
そうそう errors
.Join
互換の関数ってあったほうがいいのかなぁ。
それをするにはマルチエラー用の型を作らないといけないのだが… これはちょっと考えてみてもいいかも。
ブックマーク
参考図書
- プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)
- 丸善出版 2016-06-20
- 単行本(ソフトカバー)
- 4621300253 (ASIN), 9784621300251 (EAN), 4621300253 (ISBN), 9784621300251 (ISBN)
- 評価
著者のひとりは(あの「バイブル」とも呼ばれる)通称 “K&R” の K のほうである。この本は Go 言語の教科書と言ってもいいだろう。
- 初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド
- Jon Bodner (著), 武舎 広幸 (翻訳)
- オライリージャパン 2022-09-26
- 単行本(ソフトカバー)
- 4814400047 (ASIN), 9784814400041 (EAN), 4814400047 (ISBN)
- 評価
2021年に出た “Learning Go” の邦訳版。私は版元で PDF 版を購入。 Go 特有の語法(idiom)を切り口として Go の機能やパッケージを解説している。 Go 1.19 対応。
- デベロッパーゴースーパーゴラン Tシャツ
- Geek Go Super Golang Tees
- ウェア&シューズ
- B09C2XBC2F (ASIN)
- 評価
ついカッとなってポチった。反省はしない