নোট 2018 এ যুক্ত হয়েছে
Go 1.10 থেকে একটি strings.Builder
ধরণ রয়েছে, আরও বিশদের জন্য দয়া করে এই উত্তরটি একবার দেখুন ।
প্রাক -201x উত্তর
@ সিডি 1 এর বেঞ্চমার্ক কোড এবং অন্যান্য উত্তরগুলি ভুল। b.N
বেঞ্চমার্ক ফাংশনে সেট করার কথা নয়। এটি পরীক্ষার কার্য সম্পাদনের সময়টি স্থিতিশীল কিনা তা নির্ধারণ করতে গ-টেস্ট সরঞ্জাম দ্বারা গতিশীলভাবে সেট করা হয়েছে।
একটি বেঞ্চমার্ক ফাংশন একই পরীক্ষার b.N
সময় চালানো উচিত এবং লুপের ভিতরে পরীক্ষা প্রতিটি পুনরাবৃত্তির জন্য একই হওয়া উচিত। সুতরাং আমি এটি একটি অভ্যন্তরীণ লুপ যুক্ত করে ঠিক করেছি। কিছু অন্যান্য সমাধানের জন্য আমি মাপদণ্ডও যুক্ত করছি:
package main
import (
"bytes"
"strings"
"testing"
)
const (
sss = "xfoasneobfasieongasbg"
cnt = 10000
)
var (
bbb = []byte(sss)
expected = strings.Repeat(sss, cnt)
)
func BenchmarkCopyPreAllocate(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
bs := make([]byte, cnt*len(sss))
bl := 0
for i := 0; i < cnt; i++ {
bl += copy(bs[bl:], sss)
}
result = string(bs)
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkAppendPreAllocate(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
data := make([]byte, 0, cnt*len(sss))
for i := 0; i < cnt; i++ {
data = append(data, sss...)
}
result = string(data)
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkBufferPreAllocate(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
buf := bytes.NewBuffer(make([]byte, 0, cnt*len(sss)))
for i := 0; i < cnt; i++ {
buf.WriteString(sss)
}
result = buf.String()
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkCopy(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
data := make([]byte, 0, 64) // same size as bootstrap array of bytes.Buffer
for i := 0; i < cnt; i++ {
off := len(data)
if off+len(sss) > cap(data) {
temp := make([]byte, 2*cap(data)+len(sss))
copy(temp, data)
data = temp
}
data = data[0 : off+len(sss)]
copy(data[off:], sss)
}
result = string(data)
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkAppend(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
data := make([]byte, 0, 64)
for i := 0; i < cnt; i++ {
data = append(data, sss...)
}
result = string(data)
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkBufferWrite(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
var buf bytes.Buffer
for i := 0; i < cnt; i++ {
buf.Write(bbb)
}
result = buf.String()
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkBufferWriteString(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
var buf bytes.Buffer
for i := 0; i < cnt; i++ {
buf.WriteString(sss)
}
result = buf.String()
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
func BenchmarkConcat(b *testing.B) {
var result string
for n := 0; n < b.N; n++ {
var str string
for i := 0; i < cnt; i++ {
str += sss
}
result = str
}
b.StopTimer()
if result != expected {
b.Errorf("unexpected result; got=%s, want=%s", string(result), expected)
}
}
পরিবেশ ওএস এক্স 10.11.6, 2.2 গিগাহার্টজ ইন্টেল কোর আই 7
পরীক্ষার ফলাফল:
BenchmarkCopyPreAllocate-8 20000 84208 ns/op 425984 B/op 2 allocs/op
BenchmarkAppendPreAllocate-8 10000 102859 ns/op 425984 B/op 2 allocs/op
BenchmarkBufferPreAllocate-8 10000 166407 ns/op 426096 B/op 3 allocs/op
BenchmarkCopy-8 10000 160923 ns/op 933152 B/op 13 allocs/op
BenchmarkAppend-8 10000 175508 ns/op 1332096 B/op 24 allocs/op
BenchmarkBufferWrite-8 10000 239886 ns/op 933266 B/op 14 allocs/op
BenchmarkBufferWriteString-8 10000 236432 ns/op 933266 B/op 14 allocs/op
BenchmarkConcat-8 10 105603419 ns/op 1086685168 B/op 10000 allocs/op
উপসংহার:
CopyPreAllocate
দ্রুততম উপায়; AppendPreAllocate
নং 1 এর খুব কাছে, তবে কোডটি লেখা সহজ।
Concat
গতি এবং মেমরির ব্যবহারের জন্য উভয়ই সত্যিই খারাপ পারফরম্যান্স করেছে। এটি ব্যবহার করবেন না।
Buffer#Write
Buffer#WriteString
@ দানি-বি মন্তব্যে যা বলেছেন তার বিপরীতে এবং মূলত গতিতে একইরকম। বিবেচনা string
করা সত্যিই []byte
গো-তে রয়েছে, এটি বোধগম্য।
- বাইটস.বাফার মূলত
Copy
অতিরিক্ত বই রাখার এবং অন্যান্য স্টাফের মতো একই সমাধানটি ব্যবহার করে ।
Copy
এবং Append
64৪ এর বুটস্ট্র্যাপ আকারটি ব্যবহার করুন, এটি বাইটস-বুফারের সমান
Append
আরও মেমরি এবং বরাদ্দ ব্যবহার করুন, আমি মনে করি এটি এর ব্যবহারের বৃদ্ধি অ্যালগরিদমের সাথে সম্পর্কিত। এটি বাইটস হিসাবে দ্রুত স্মৃতি বাড়ছে না B বাফার
প্রস্তাবনা:
- সাধারণ কাজের জন্য যেমন ওপি যা চায়, আমি তা ব্যবহার করব
Append
বা করব AppendPreAllocate
। এটি যথেষ্ট দ্রুত এবং সহজেই ব্যবহারযোগ্য।
- যদি একই সাথে বাফারটি পড়তে এবং লেখার প্রয়োজন হয় তবে
bytes.Buffer
অবশ্যই ব্যবহার করুন । এটি এর জন্য ডিজাইন করা হয়েছে।