Skip to content

パフォーマンス

govalid は純粋なリフレクションを使います——コード生成なし、ウォーム アップが必要なキャッシュもありません。以下の数字は Apple M1 Pro 上 の Go 1.26(go test -bench=. -benchmem)で計測したものです:

text
BenchmarkCheck_Simple_Valid-10      745966     1655 ns/op    1136 B/op    29 allocs/op
BenchmarkCheck_Simple_Invalid-10    713349     1644 ns/op    1160 B/op    31 allocs/op
BenchmarkCheck_Rich_Valid-10        262418     4748 ns/op    3216 B/op    73 allocs/op
BenchmarkParseRules-10             2852902      412 ns/op     520 B/op    14 allocs/op

10 フィールドの "rich" 構造体(携帯番号、メール、長さ・範囲チェック を含む)に対して、コアあたり約 21 万バリデーション/秒、特別な 最適化なしです。

何にいくらかかるか

操作コスト
タグごとの parseRules~400 ns / 14 allocs
チェッカー呼び出しごと各々 ns 単位、正規表現駆動のものは様々
リフレクションでのフィールド走査アロケーションを支配
ローカライズされたメッセージ描画非自明テンプレートあたり 1 つの strings.NewReplacer

ホットパスとコツ

  • 正規表現は一度だけコンパイル。 組み込みパターンはパッケージ レベルの regexp.MustCompile です。カスタムチェッカーも同じパター ンに従ってください。
  • 構造体型を再利用。 parseRules は単一の Check 呼び出し内で タグ毎のルールスライスをキャッシュしますが、呼び出し間ではキャッ シュしません。
  • リクエスト毎に一度バリデート。 govalid は HTTP ハンドラー内で インラインに呼ぶのに十分速く、「バリデーションキャッシュ」は不要 です。
  • 巨大な list: ルールは避ける。 各エントリは fmt.Sprintf("%v", value) で比較されます。値が数十なら問題ない ですが、数千なら map[string]struct{} を使うカスタムチェッカーへ 切り替えてください。

並行性

Check は並行に呼び出して安全です。ホットパス上のパッケージレベル 状態(Checkers、ロケールテンプレートマップ)は書き込みに対して 同期されていません——カスタムチェッカーとテンプレートはプロ グラム起動時、goroutine が Check をヒットし始める前に登録して ください。

ライブラリは go test -race 下で、共有構造体・独立構造体の両方の 並行ワークロードを実行済みです。

ファズカバレッジ

リポジトリには 2 つのファズターゲットが入っています:

sh
go test -run=^$ -fuzz=FuzzCheck     -fuzztime=10s ./...
go test -run=^$ -fuzz=FuzzParseRules -fuzztime=10s ./...

合計で 数百万回の実行 を経てパニックを起こしていません。クラッ シュする入力を見つけたらシードを添えて issue を立ててください。

MIT ライセンスのもとで公開されています。