เนื่องจากฉันไม่คิดว่าคำตอบที่นี่จะครอบคลุมทุกสิ่งฉันจึงต้องการเพิ่มเติมเล็กน้อยที่นี่
Console.WriteLine(string format, params object[] pars)
โทร string.Format
โทรเครื่องหมาย '+' หมายถึงการต่อสตริงเข้าด้วยกัน ฉันไม่คิดว่าสิ่งนี้จะเกี่ยวข้องกับสไตล์เสมอไป ฉันมักจะผสมสองสไตล์ขึ้นอยู่กับบริบทของฉัน
คำตอบสั้น ๆ
การตัดสินใจที่คุณกำลังเผชิญนั้นเกี่ยวข้องกับการจัดสรรสตริง ฉันจะพยายามทำให้มันง่าย
บอกว่าคุณมี
string s = a + "foo" + b;
หากคุณดำเนินการสิ่งนี้จะมีการประเมินดังนี้:
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
tmp
ที่นี่ไม่ได้เป็นตัวแปรในท้องถิ่น แต่เป็นเพียงชั่วคราวสำหรับ JIT (มันถูกผลักลงบนกอง IL) หากคุณกดสตริงบนสแต็ก (เช่นldstr
ใน IL สำหรับตัวอักษร) คุณจะใส่การอ้างอิงไปยังตัวชี้สตริงบนสแต็ก
ช่วงเวลาที่คุณโทร concat
การอ้างอิงนี้กลายเป็นปัญหาเนื่องจากไม่มีการอ้างอิงสตริงที่มีทั้งสองสตริง ซึ่งหมายความว่า. NET จำเป็นต้องจัดสรรบล็อกหน่วยความจำใหม่แล้วกรอกด้วยสองสาย เหตุผลนี้เป็นปัญหาเนื่องจากการจัดสรรค่อนข้างแพง
คำถามใดที่เปลี่ยนเป็น: คุณจะลดจำนวนconcat
การปฏิบัติงานได้อย่างไร
ดังนั้นคำตอบคร่าวๆคือstring.Format
สำหรับ> 1 concats '+' จะใช้ได้ดีสำหรับ 1 concat และถ้าคุณไม่สนใจเกี่ยวกับการเพิ่มประสิทธิภาพไมโครประสิทธิภาพstring.Format
จะทำงานได้ดีในกรณีทั่วไป
หมายเหตุเกี่ยวกับวัฒนธรรม
แล้วมีบางสิ่งที่เรียกว่าวัฒนธรรม ...
string.Format
ช่วยให้คุณสามารถใช้CultureInfo
ในการจัดรูปแบบของคุณ ตัวดำเนินการอย่างง่าย '+' ใช้วัฒนธรรมปัจจุบัน
นี่เป็นคำพูดที่สำคัญอย่างยิ่งหากคุณกำลังเขียนรูปแบบไฟล์และ f.ex double
ค่าที่คุณ 'เพิ่ม' ให้กับสตริง บนเครื่องที่แตกต่างกันคุณอาจจบลงด้วยสตริงแตกต่างกันถ้าคุณไม่ได้ใช้กับอย่างชัดเจนstring.Format
CultureInfo
F.ex. พิจารณาสิ่งที่เกิดขึ้นหากคุณเปลี่ยน '.' สำหรับ ',' ในขณะที่เขียนไฟล์ค่าคั่นด้วยจุลภาคของคุณ ... ในภาษาดัตช์ตัวคั่นทศนิยมเป็นเครื่องหมายจุลภาคดังนั้นผู้ใช้ของคุณอาจได้รับความประหลาดใจ 'ตลก'
คำตอบที่ detailled เพิ่มเติม
หากคุณไม่ทราบขนาดที่แน่นอนของสตริงไว้ก่อนหน้านี้ควรใช้นโยบายเช่นนี้เพื่อกำหนดขนาดบัฟเฟอร์ที่คุณใช้โดยรวม พื้นที่หย่อนถูกเติมเต็มครั้งแรกหลังจากนั้นข้อมูลจะถูกคัดลอก
การเติบโตหมายถึงการจัดสรรบล็อกหน่วยความจำใหม่และคัดลอกข้อมูลเก่าไปยังบัฟเฟอร์ใหม่ บล็อกเก่าของหน่วยความจำนั้นจะถูกปล่อยออกมา คุณจะได้รับบรรทัดล่าง ณ จุดนี้: การเติบโตคือการดำเนินการที่มีราคาแพง
วิธีปฏิบัติที่เป็นประโยชน์ที่สุดในการทำเช่นนี้คือการใช้นโยบายภาพรวม นโยบายที่พบบ่อยที่สุดคือการรวม overallocate buffers ในระดับ 2 แน่นอนคุณต้องฉลาดกว่านี้เล็กน้อย (เนื่องจากไม่มีเหตุผลที่จะเติบโตจาก 1,2,4,8 หากคุณรู้ว่าคุณต้องการ 128 ตัวอักษร ) แต่คุณจะได้รับภาพ นโยบายช่วยให้มั่นใจว่าคุณไม่ต้องการการดำเนินการที่มีราคาแพงมากเกินไปที่ฉันอธิบายไว้ข้างต้น
StringBuilder
เป็นคลาสที่ overallocates บัฟเฟอร์พื้นฐานเป็นกำลังสอง string.Format
ใช้StringBuilder
ภายใต้ประทุน
สิ่งนี้ทำให้การตัดสินใจของคุณเป็นการแลกเปลี่ยนพื้นฐานระหว่าง overallocate และผนวก (-multiple) (วัฒนธรรม w / wo) หรือเพียงแค่จัดสรรและผนวก
string.Format
ที่ไม่ได้ใช้คุณสมบัติการจัดรูปแบบคอมโพสิตใด ๆ (เช่นง่าย ๆ{0}
) และแทนที่ด้วยการต่อสตริงที่เร็วขึ้นอย่างมาก ฉันสงสัยว่าความสำเร็จดังกล่าวสามารถทำได้โดยนักเขียน IL คนปัจจุบันเช่น PostSharp