Performance comparison of string concatenation in Go language

  sonic0002        2024-05-13 00:33:20       2,295        0          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

ในภาษา 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


  0 COMMENT


No comment for this article.



  RANDOM FUN

Documentation is like sex