การแก้ไขสตริงเทียบกับสตริงรูปแบบ


114

มีความแตกต่างของประสิทธิภาพที่สังเกตได้ระหว่างการใช้การแก้ไขสตริง:

myString += $"{x:x2}";

เทียบกับ String.Format ()?

myString += String.Format("{0:x2}", x);

ฉันแค่ถามเพราะ Resharper กำลังแจ้งการแก้ไขและฉันเคยโดนหลอกมาก่อน


4
ทำไมไม่ลองทั้งสองอย่างและดูว่าคุณสังเกตเห็นความแตกต่างหรือไม่?
Blorgbeard ออก

57
@Blorgbeard พูดตรงๆฉันขี้เกียจ และฉันคิดว่ามันจะใช้เวลาน้อยลงถ้าคุณคนใดคนหนึ่งที่ยืนหยัดที่ชาย / หญิงรู้คำตอบ
Krythic

26
ฉันชอบที่ฉันถามคำถามนี้เป็นครั้งแรกมันได้รับการโหวตให้ลืมเลือนและตอนนี้อีกสองปีต่อมาก็ถึง +21
Krythic

47
อย่างจริงจัง. ใครสงสัยในประโยชน์ของคำถามนี้ได้อย่างไร? คุณนึกภาพออกไหมว่าเวลาทำงานทั้งหมดที่เสียไปถ้าทุกคนที่ถามคำถามนี้ต้อง 'ลองดูด้วยตัวเองดูไหม?' แม้ว่าจะใช้เวลาเพียง 5 นาที แต่ก็ให้คูณกับนักพัฒนากว่า 10,000 คนที่ดูคำถามนี้จนถึงตอนนี้ แล้วคุณจะทำอย่างไรเมื่อเพื่อนร่วมงานสงสัยผลลัพธ์ของคุณ ทำใหม่ทั้งหมดหรือไม่? หรืออาจจะแค่อ้างอิงถึงโพสต์ SO นี้ นั่นคือสิ่งที่มีไว้เพื่อ
BTownTKD

8
@BTownTKD นั่นคือพฤติกรรม Stackoverflow ทั่วไปสำหรับคุณ หากใครใช้ไซต์ตามวัตถุประสงค์พวกเขาจะแปลกแยกทันที นี่เป็นหนึ่งในเหตุผลที่ฉันคิดว่าเราควรได้รับอนุญาตให้แบนบัญชีโดยรวม หลายคนไม่สมควรที่จะอยู่ในไซต์นี้
Krythic

คำตอบ:


72

ที่สังเกตได้คือญาติ อย่างไรก็ตาม: การแก้ไขสตริงถูกเปลี่ยนเป็นstring.Format()เวลาคอมไพล์ดังนั้นจึงควรได้ผลลัพธ์เดียวกัน

แม้ว่าจะมีความแตกต่างเล็กน้อยดังที่เราทราบได้จากคำถามนี้การต่อสายอักขระในตัวระบุรูปแบบจะทำให้เกิดการstring.Concat()เรียกเพิ่มเติม


4
ที่จริงแล้วการแก้ไขสตริงอาจรวมเข้ากับการต่อสายอักขระได้ในบางกรณี (เช่นเมื่อใช้ a int) var a = "hello"; var b = $"{a} world";คอมไพล์เพื่อเชื่อมต่อสตริง var a = "hello"; var b = $"{a} world {1}";คอมไพล์เป็นรูปแบบสตริง
Omar Muscatello

5

การแก้ไขสตริงจะเปลี่ยนเป็นสตริงรูปแบบ () ในเวลาคอมไพล์

นอกจากนี้ในสตริงรูปแบบคุณสามารถระบุเอาต์พุตหลายรายการสำหรับอาร์กิวเมนต์เดียวและรูปแบบเอาต์พุตที่แตกต่างกันสำหรับอาร์กิวเมนต์เดียว แต่การแก้ไขสตริงนั้นอ่านได้ง่ายกว่าฉันเดา ดังนั้นขึ้นอยู่กับคุณ

a = string.Format("Due date is {0:M/d/yy} at {0:h:mm}", someComplexObject.someObject.someProperty);

b = $"Due date is {someComplexObject.someObject.someProperty:M/d/yy} at {someComplexObject.someObject.someProperty:h:mm}";

มีผลการทดสอบประสิทธิภาพบางส่วนhttps://koukia.ca/string-interpolation-vs-string-format-string-concat-and-string-builder-performance-benchmarks-c1dad38032a


2
สตริงแก้ไขเป็นเพียงแค่บางครั้งString::Formatกลายเป็น String::Concatและบางครั้งเข้า และการทดสอบประสิทธิภาพในหน้านั้นไม่ได้มีความหมายจริงๆ: จำนวนข้อโต้แย้งที่คุณส่งผ่านไปยังแต่ละวิธีนั้นขึ้นอยู่กับ concat ไม่ได้เร็วที่สุดเสมอไปนักสร้างสตริงไม่ใช่คนที่ช้าที่สุดเสมอไป
Matthias Burger

3

คำถามเกี่ยวกับประสิทธิภาพ แต่ชื่อเรื่องบอกว่า "vs" ดังนั้นฉันจึงรู้สึกว่าต้องเพิ่มคะแนนอีกเล็กน้อยบางส่วนก็มีความเห็น

  • การแปล

    • การแก้ไขสตริงไม่สามารถแปลเป็นภาษาท้องถิ่นได้เนื่องจากเป็นรหัสแบบอินไลน์ string.Formatก่อนที่จะแปลว่ามันได้กลายเป็น อย่างไรก็ตามมีเครื่องมือสำหรับสิ่งนั้น (เช่นReSharper)
  • การบำรุงรักษา (ความคิดเห็นของฉัน)

    • string.Formatสามารถอ่านได้มากขึ้นเนื่องจากเน้นไปที่ประโยคที่ฉันต้องการจะใช้เป็นวลีเช่นเมื่อสร้างข้อความแสดงข้อผิดพลาดที่ดีและมีความหมาย ใช้{N}ตัวยึดตำแหน่งทำให้ฉันมีความยืดหยุ่นมากขึ้นและง่ายต่อการแก้ไขในภายหลัง
    • นอกจากนี้ตัวระบุรูปแบบแบบอินไลน์ในการตีความยังง่ายต่อการอ่านผิดและง่ายต่อการลบพร้อมกับนิพจน์ระหว่างการเปลี่ยนแปลง
    • เมื่อใช้นิพจน์ที่ซับซ้อนและยาวการแก้ไขจะทำให้อ่านและดูแลรักษาได้ยากขึ้นอย่างรวดเร็วดังนั้นในแง่นี้จึงไม่สามารถปรับขนาดได้ดีเมื่อโค้ดมีการพัฒนาและซับซ้อนมากขึ้น string.Formatมีแนวโน้มที่จะเกิดสิ่งนี้น้อยกว่ามาก
    • ในตอนท้ายของวันที่มันเป็นเรื่องของการแยกของความกังวล: ผมไม่ชอบที่จะผสมว่ามันควรจะนำเสนอกับสิ่งที่ควรจะนำเสนอ

จากสิ่งเหล่านี้ฉันตัดสินใจที่จะยึดติดกับstring.Formatรหัสส่วนใหญ่ของฉัน อย่างไรก็ตามฉันได้เตรียมวิธีการขยายเพื่อให้มีวิธีการเข้ารหัสที่คล่องขึ้นซึ่งฉันชอบมากขึ้น การใช้งานของส่วนขยายเป็นแบบซับเดียวและดูเหมือนว่าจะใช้งานได้

var myErrorMessage = "Value must be less than {0:0.00} for field {1}".FormatWith(maximum, fieldName);

การสอดแทรกเป็นคุณสมบัติที่ยอดเยี่ยมอย่าเข้าใจฉันผิด แต่ IMO เป็นภาษาที่ดีที่สุดในภาษาเหล่านั้นซึ่งไม่มีstring.Formatคุณสมบัติเหมือนเช่น JavaScript


ขอขอบคุณสำหรับการเพิ่มสิ่งนี้
Krythic

1
ฉันไม่เห็นด้วยกับการบำรุงรักษา ได้รับ ReSharper ทำให้ง่ายต่อการจับคู่ค่าที่แทรกกับดัชนีที่เกี่ยวข้อง (และในทางกลับกัน) แต่ฉันคิดว่ามันยังมีภาระทางปัญญามากกว่าที่จะคิดออกว่า{3}เป็น X หรือ Y โดยเฉพาะอย่างยิ่งถ้าคุณเริ่มจัดรูปแบบของคุณใหม่ ตัวอย่าง Madlibs: $"It was a {adjective} day in {month} when I {didSomething}"vs string.Format("It was a {0} day in {1} when I {2}", adjective, month, didSomething)-> $"I {didSomething} on a {adjective} {month} day"vsstring.Format("I {2} on a {0} {1} day", adjective, month, didSomething)
drzaus

@drzaus ขอบคุณสำหรับการแบ่งปันความคิดของคุณ คุณมีจุดดี แต่จะจริงก็ต่อเมื่อเราใช้เฉพาะตัวแปรท้องถิ่นที่เรียบง่ายและมีชื่อดี สิ่งที่ฉันเคยเห็นมาหลายครั้งคือนิพจน์ที่ซับซ้อนการเรียกใช้ฟังก์ชันอะไรก็ตามที่ใส่เข้าไปในสตริงที่ถูกสอดแทรก ด้วยstring.Formatฉันคิดว่าคุณมีแนวโน้มที่จะเกิดปัญหานี้น้อยกว่ามาก แต่อย่างไรก็ตามนี่คือเหตุผลที่ฉันเน้นย้ำว่านั่นคือความคิดของฉัน :)
ZoltánTamási
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.