空文字列確認は長さをとるべきか?

TL;DR s == ""とlen(s) == 0は等価 文字列比較か、長さ比較か Go言語で文字列が空かどうかを調べるには次の二つの方法があります。 1 2 3 4 5 6 7 8 9 // 1: 文字列を空文字列と比較する if s == "" { // do something } // 2: 文字列の長さが0かどうか調べる if len(s) == "" { // do something } 標準パッケージ・サードパーティパッケージともに、どちらの書き方も散見されます。 どちらを使うのが良いのでしょうか? 答えはどちらでも良いだそうです。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package benchmark_test import "testing" var somethingString = "hogehogefugafuga" func BenchmarkCompareString(b *testing....

2019-10-09 · nasa9084

array/sliceに対する存在確認関数のベンチマーク

Pythonでいうところの、次の様な条件式を実現する関数を書きたかった。 1 2 3 4 5 ls = ["foo", "bar", "baz"] s = "baz" if s in ls: print("FOOBAR!") 対象がリストの時、普段なら普通にfor文を回すのですが、今回やりたかったのは定数値の一覧にあるかどうか、だったのと、定数の数も少なかったので、とりあえずで以下の様に実装していました。 1 2 3 4 5 func something(s string) error { if s != "foo" && s != "bar" && s != "baz" { return errors.New("value invalid") } } 流石に雑すぎるので、リファクタリングしよう、と思ったのですが、「はて、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....

2018-06-26 · nasa9084

strings.Builderとbytes.BufferのWrite系関数のベンチマーク

TL; DR 平均して見るとstrings.Builder#WriteXXXの方が速そう strings.Builder Go 1.10からstrings.Builder構造体が追加されました。 公式ドキュメントには、 A Builder is used to efficiently build a string using Write methods. It minimizes memory copying. The zero value is ready to use. Do not copy a non-zero Builder. と説明が書かれています。 おそらく、これまで文字列の組み立てをする際にはbytes.Bufferを使っている場合が多かったと思われますが、そういった目的の選択肢として作られたようです。 が、説明を読んでもいまいち違いがわかりません。 とりあえず、bytes.Bufferとstrings.Builderでは速度面で違いがあるのか調べるべく、ベンチマークを実施しました。 条件 実行した環境 MacBook Air MacOS Sierra 10.12.6 CPU: Core i7 1.7GHz メモリ: 8GB 実行する関数 Write WriteByte WriteRune WriteString exec 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 $ for i in {1....

2018-03-05 · nasa9084

go-redis, redigo, boltのベンチマークを取ってみた

tl;dr データベースに接続済みの状態からstringで値をセット・ゲットするベンチマーク BoltのGetがめちゃめちゃ速い go-redisよりはredigoの方が速い Boltのセットがメモリアロケーションすごく多い result 1 2 3 4 5 6 7 8 9 $ go test -bench . BenchmarkRedisSet-4 10000 246527 ns/op 249 B/op 9 allocs/op BenchmarkRedisGet-4 5000 231569 ns/op 225 B/op 9 allocs/op BenchmarkRedigoSet-4 5000 204545 ns/op 70 B/op 4 allocs/op BenchmarkRedigoGet-4 5000 209392 ns/op 80 B/op 6 allocs/op BenchmarkBoltSet-4 10000 166142 ns/op 34287 B/op 57 allocs/op BenchmarkBoltGet-4 1000000 1140 ns/op 488 B/op 8 allocs/op PASS ok practices/redis-bolt-benchmark 8....

2017-09-07 · nasa9084

io.Writer.Write()とfmt.Fprintf()のBenchmark

tl;dr 基本的にio.Writer.Write()を使用するのが高速なようです。 result 1 2 3 4 5 6 $ go test -bench . -benchmem BenchmarkWrite-4 30000000 48.7 ns/op 16 B/op 1 allocs/op BenchmarkWriteWithBytes-4 500000000 3.95 ns/op 0 B/op 0 allocs/op BenchmarkFprintf-4 20000000 91.5 ns/op 0 B/op 0 allocs/op BenchmarkWriteTo-4 100000000 10.0 ns/op 0 B/op 0 allocs/op BenchmarkWriteWithBufferBytes-4 300000000 4.31 ns/op 0 B/op 0 allocs/op source 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package main_test import ( "bytes" "fmt" "io" "net/http" "testing" ) var s = "Hello, my world" var bs = []byte(s) var buf = bytes....

2017-09-02 · nasa9084