Performance comparison of string concatenation in Go language

English 简体中文 繁体中文 ภาษาไทย Tiếng Việt
Summary

Go string concatenation methods exhibit significant performance differences, with the simple + operator and fmt.Sprintf proving highly inefficient due to frequent memory reallocations. Benchmarks demonstrate that strings.Builder and bytes.Buffer offer vastly superior performance by leveraging an underlying []byte slice with optimized allocation strategies. For the absolute highest performance, manually pre-allocating a []byte slice is most effective, though it demands more careful management. Developers should generally opt for strings.Builder for its excellent balance of usability and efficiency, reserving pre-allocated []byte slices for critical, performance-sensitive applications.

ในภาษา Go การต่อสตริงเป็นการดำเนินการที่หลีกเลี่ยงไม่ได้ในระหว่างการพัฒนา และการต่อสตริงอย่างมีประสิทธิภาพเป็นสิ่งสำคัญในการปรับปรุงประสิทธิภาพของแอปพลิเคชัน บทความนี้จะเจาะลึกหลายวิธีทั่วไปในการต่อสตริง ให้การเปรียบเทียบประสิทธิภาพ และเสนอข้อเสนอแนะในการเพิ่มประสิทธิภาพเพื่อช่วยให้นักพัฒนาเขียนโค้ดที่มีประสิทธิภาพมากขึ้น

วิธีการต่อสตริงทั่วไป

ในภาษา Go วิธีการต่อสตริงทั่วไป ได้แก่:

การใช้ตัวดำเนินการ + สำหรับการต่อสตริง

มันง่ายและตรงไปตรงมา แต่การต่อสตริงแต่ละครั้งจะสร้างสตริงใหม่ ส่งผลให้เกิดโอเวอร์เฮดในการจัดสรรหน่วยความจำอย่างมาก

func plusConcat(n int, str string) string {
	s := ""
	for i := 0; i < n; i++ {
		s += str
	}
	return s
}

การใช้ fmt.Sprintf สำหรับการต่อสตริงแบบฟอร์แมต

มันรองรับคุณสมบัติการฟอร์แมตที่หลากหลาย แต่ประสิทธิภาพไม่ดีเท่าวิธีอื่นๆ

func sprintfConcat(n int, str string) string {
	s := ""
	for i := 0; i < n; i++ {
		s = fmt.Sprintf("%s%s", s, str)
	}
	return s
}

การใช้ strings.Builder

เปิดตัวใน Go 1.10 ชนิดนี้ได้รับการออกแบบมาโดยเฉพาะสำหรับการต่อสตริงอย่างมีประสิทธิภาพ

func builderConcat(n int, str string) string {
	var builder strings.Builder
	for i := 0; i < n; i++ {
		builder.WriteString(str)
	}
	return builder.String()
}

การใช้บัฟเฟอร์ bytes.Buffer

มันได้รับการสนับสนุนโดยสไลซ์ []byte แต่การแปลงเป็นสตริงทำให้เกิดการจัดสรรหน่วยความจำเพิ่มเติม

func bufferConcat(n int, str string) string {
	buf := new(bytes.Buffer)
	for i := 0; i < n; i++ {
		buf.WriteString(str)
	}
	return buf.String()
}

การใช้การต่อสไลซ์ []byte

การจัดการหน่วยความจำด้วยตนเอง ทำงานได้ดีแต่มีแนวโน้มที่จะเกิดข้อผิดพลาด

func preByteConcat(n int, str string) string {
	buf := make([]byte, 0, n*len(str))
	for i := 0; i < n; i++ {
		buf = append(buf, str...)
	}
	return string(buf)
}

การเปรียบเทียบประสิทธิภาพ

ในการเปรียบเทียบประสิทธิภาพของวิธีการต่อสตริงที่แตกต่างกัน เราจะต่อสตริงที่มีความยาว 10 10,000 ครั้งและทดสอบเวลาที่ใช้และการใช้หน่วยความจำ นี่คือผลการทดสอบสำหรับวิธีการต่อสตริงที่แตกต่างกัน:

 

time/op (ms)

memory/op(MB)

allocs/op

การต่อสตริง +

56

530

10026

fmt.Sprintf

112

835

37435

strings.Builder

0.13

0.5

23

bytes.Buffer

0.14

0.4

13

[]byte จัดสรรล่วงหน้า

0.07

0.2

2

หลักการเบื้องหลังประสิทธิภาพ

ทำไม strings.Builder จึงทำงานได้ดีกว่าวิธีอื่นๆ เหตุผลอยู่ที่กลไกการจัดสรรหน่วยความจำ

สำหรับการต่อสตริง + การต่อสตริงแต่ละครั้งจะสร้างสตริงใหม่ ทำให้เกิดการจัดสรรหน่วยความจำใหม่ต่อเนื่อง

strings.Builder ใช้สไลซ์ []byte ที่อยู่เบื้องหลังและใช้กลยุทธ์การจัดสรรหน่วยความจำแบบเลขชี้กำลัง หลีกเลี่ยงการจัดสรรหน่วยความจำบ่อยครั้ง

เมื่อแปลงเป็นสตริง มันจะส่งคืนสไลซ์ []byte ที่อยู่เบื้องหลังโดยตรง หลีกเลี่ยงการจัดสรรหน่วยความจำเพิ่มเติม

ข้อเสนอแนะในการเพิ่มประสิทธิภาพ

เมื่อพิจารณาถึงความสามารถในการใช้งานและประสิทธิภาพ ขอแนะนำให้ใช้ strings.Builder สำหรับการต่อสตริง หากต้องการประสิทธิภาพสูงมาก ให้พิจารณาใช้หน่วยความจำที่จัดสรรล่วงหน้าด้วยการต่อสไลซ์ []byte

สรุป

บทความนี้เปรียบเทียบประสิทธิภาพของวิธีการต่อสตริงที่แตกต่างกัน วิเคราะห์หลักการพื้นฐาน และให้ข้อเสนอแนะในการเพิ่มประสิทธิภาพ ในการพัฒนาจริง ให้เลือกวิธีการต่อสตริงที่เหมาะสมตามความต้องการด้านประสิทธิภาพเพื่อหลีกเลี่ยงโอเวอร์เฮดด้านประสิทธิภาพที่ไม่จำเป็น เราหวังว่าบทความนี้จะให้ความช่วยเหลือในสถานการณ์ที่เกี่ยวข้องกับการต่อสตริง ยินดีต้อนรับความคิดเห็นที่แตกต่างกันในความคิดเห็น

COMPARISON PERFORMANCE STRING CONCATENATION

  RELATED

  COMMENTS

0

No comment for this article.