Pythonでいうところの、次の様な条件式を実現する関数を書きたかった。
|
|
対象がリストの時、普段なら普通にfor文を回すのですが、今回やりたかったのは定数値の一覧にあるかどうか、だったのと、定数の数も少なかったので、とりあえずで以下の様に実装していました。
|
|
流石に雑すぎるので、リファクタリングしよう、と思ったのですが、「はて、for文挟んだら遅くなったりしないだろうか」などと考えてしまったのでベンチマークを取りました。
TL; DR
素直にfor文を回しても大して問題はなさそう
result
今回取ったベンチマークは6種類です。
- for-range文を回す
- for文を回す
map[string]struct{}
を集合として取り扱ってみる&&
,||
でつなぐ- switch文を使う
sort.SearchStrings()
を使う
6番目のsort.SearchStrings()
を使う方法はstackoverflow
に書いてあった方法で、二分探索をしてくれるというのでやってみました。
結果は次の通り。
BenchmarkInByForRange-4 200000000 9.34 ns/op 0 B/op 0 allocs/op
BenchmarkInByFor-4 100000000 10.1 ns/op 0 B/op 0 allocs/op
BenchmarkInByMap-4 200000000 7.79 ns/op 0 B/op 0 allocs/op
BenchmarkInByAnd-4 1000000000 2.85 ns/op 0 B/op 0 allocs/op
BenchmarkInBySwitch-4 2000000000 1.39 ns/op 0 B/op 0 allocs/op
BenchmarkInBySortSearchStrings-4 10000000 179 ns/op 32 B/op 1 allocs/op
まぁ予想通りではあるものの、sort.SearchStrings()
を使う方法は遅いですね。これはこの関数の「事前にリストがソート済みであること」という条件のために関数内でソートをしてるからだと思われます。(実際、ソート済みのリストを使って、関数内でソートをしないようにすると1/4くらいにはなる)
一番速かったのはswitch文を使ったやつで、これも予想通り(Go言語のswitchさん、すごく速いのは知っていた)。
とはいえ、(sort.SearchString()
は除いて)せいぜい一桁ナノ秒の三倍程度しか違わないので、よほどのことが無ければ普通にfor文を回す方法でも問題ないかな、という程度の速度差でした。