Y

ISUCON12予選の復習をしました 5

この記事は何か?

ISUCON12の復習記録です。

第5回はISUCON12 予選の解説 (Node.jsでSQLiteのまま10万点行く方法)の「5 dispenseIDでMySQLを使うのをやめる」を試します。

目次

  1. 「5 dispenseIDでMySQLを使うのをやめる」を試す

1. 「5 dispenseIDでMySQLを使うのをやめる」を試す

発番についてはもともとdispenseIDで生成するのが整数値ではなく文字列値なので、比較的どんな形式でも受け入れるようにベンチマーク/フロントエンドは実装されていました。定番なのはUUIDとかULIDとかになるかと思いますが、普通に ${tenantId}-${unixepochnano} みたいな感じのいくつかのIDの文字列連結でも行けるようになっています。

これは僕も解決できた問題でしたが、「var id int64」を使っていたので、整数値を返す必要があると勘違いしてランダム関数を利用しましたが、文字列値でよいので単純にUUIDを利用すればよかったようです。

go get github.com/google/uuid を実行

@@ -32,6 +32,7 @@ import (
        _ "net/http/pprof"

        "golang.org/x/exp/slices"
+       "github.com/google/uuid"
 )

 const (
@@ -104,6 +105,7 @@ func createTenantDB(id int64) error {

 // システム全体で一意なIDを生成する
 func dispenseID(ctx context.Context) (string, error) {
+       /*
        var id int64
        var lastErr error
        for i := 0; i < 100; i++ {
@@ -126,6 +128,9 @@ func dispenseID(ctx context.Context) (string, error) {
                return fmt.Sprintf("%x", id), nil
        }
        return "", lastErr
+       */
+       uuidObj, _ := uuid.NewUUID()
+       return uuidObj.String(), nil
 }
  • 変更前のスコア
22:04:15.150282 SCORE: 6058 (+6058 0(0%))
  • 変更後のスコア
22:36:19.017277 SCORE: 6390 (+6390 0(0%))

感想

dispenseID()が以下のように「文字列」を返していて、 DBの型も「文字列型」ということをすぐ理解できたら、時間短縮できていたと思います。これもコードを読む機会が少ないことが原因だと反省しています。

var id int64
return fmt.Sprintf("%x", id), nil ← 16進数(a-f小文字)を返す

参考

1 ISUCON12 予選の解説 (Node.jsでSQLiteのまま10万点行く方法)