いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-338 ([]byteに対して文字列を追加するやり方の速度比較)(fmt.Sprintf, fmt.Appenf, 直接append)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

Go 1.21 で追加された slog のドキュメントを見ていると以下の記載がありました。

slogのハンドラ作成ガイドドキュメント より引用。

One simple change you can make is to replace calls to fmt.Sprintf or fmt.Appendf with direct appends to the buffer. For example, our IndentHandler appends string attributes to the buffer like so:

直接 append したら一番速度的には出るよと。

試してみた

package main

import (
    "fmt"
    "strconv"
    "testing"
)

func BenchmarkUseFmtSprintf(b *testing.B) {
    b.StopTimer()
    buf := make([]byte, 0, 1024*1024*500)
    b.StartTimer()

    for i := 0; i < b.N; i++ {
        s := fmt.Sprintf("%s:%d\n", "key", i)
        buf = append(buf, s...) //lint:ignore SA4010 It's ok.
    }
}

func BenchmarkUseFmtAppendf(b *testing.B) {
    b.StopTimer()
    buf := make([]byte, 0, 1024*1024*500)
    b.StartTimer()

    for i := 0; i < b.N; i++ {
        buf = fmt.Appendf(buf, "%s:%d\n", "key", i)
    }
}

func BenchmarkUseDirectAppend(b *testing.B) {
    b.StopTimer()
    buf := make([]byte, 0, 1024*1024*500)
    b.StartTimer()

    for i := 0; i < b.N; i++ {
        buf = append(buf, "key:"...)          //lint:ignore SA4010 It's ok.
        buf = append(buf, strconv.Itoa(i)...) //lint:ignore SA4010 It's ok.
        buf = append(buf, '\n')               //lint:ignore SA4010 It's ok.
    }
}

以下、Gitpodで試してみた結果です。

$ task
goos: linux
goarch: amd64
pkg: github.com/devlights/try-golang/examples/singleapp/speed_diff_append_string_to_byteslice
cpu: AMD EPYC 7B13
BenchmarkUseFmtSprintf-16        3160230               320.0 ns/op
BenchmarkUseFmtAppendf-16        9861033               133.7 ns/op
BenchmarkUseDirectAppend-16     21009861                83.87 ns/op
PASS
ok      github.com/devlights/try-golang/examples/singleapp/speed_diff_append_string_to_byteslice        7.914s

確かにそうですね。処理としては冗長な感じになっちゃいますが、回数がとても多くて速度が欲しい場合に使えそうな感じ。

勉強になりました。m( )m

今回のサンプルは以下にアップしてあります。

github.com

参考情報

github.com

pkg.go.dev

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。