มีคลาสสตริงใน Python เหมือนStringBuilder
ใน C # หรือไม่?
มีคลาสสตริงใน Python เหมือนStringBuilder
ใน C # หรือไม่?
คำตอบ:
ไม่มีความสัมพันธ์แบบหนึ่งต่อหนึ่ง สำหรับบทความที่ดีจริงๆโปรดดูการต่อสตริงที่มีประสิทธิภาพใน Python :
การสร้างสตริงที่ยาวในภาษา Python progamming บางครั้งอาจส่งผลให้โค้ดทำงานช้ามาก ในบทความนี้ฉันตรวจสอบประสิทธิภาพการคำนวณของวิธีการต่อสายอักขระต่างๆ
ฉันใช้รหัสของ Oliver Crow (ลิงก์ที่ให้โดย Andrew Hare) และปรับแต่งเล็กน้อยเพื่อปรับแต่ง Python 2.7.3 (โดยใช้แพ็คเกจ timeit) ฉันใช้คอมพิวเตอร์ส่วนบุคคล Lenovo T61, RAM 6GB, Debian GNU / Linux 6.0.6 (บีบ)
นี่คือผลลัพธ์สำหรับการทำซ้ำ 10,000 ครั้ง:
method1: 0.0538418292999 วินาที ขนาดกระบวนการ 4800 kb method2: 0.22602891922 วินาที ขนาดกระบวนการ 4960 kb วิธีที่ 3: 0.0605459213257 วินาที ขนาดกระบวนการ 4980 kb method4: 0.0544030666351 วินาที ขนาดกระบวนการ 5536 kb method5: 0.0551080703735 วินาที ขนาดกระบวนการ 5272 kb method6: 0.0542731285095 วินาที ขนาดกระบวนการ 5512 kb
และสำหรับการทำซ้ำ 5,000,000 ครั้ง (วิธีที่ 2 ถูกละเว้นเพราะมันทำงานช้าเกินไปเช่นตลอดไป):
method1: 5.88603997231 วินาที ขนาดกระบวนการ 37976 kb method3: 8.40748500824 วินาที ขนาดกระบวนการ 38024 kb วิธี 4: 7.96380496025 วินาที ขนาดกระบวนการ 321968 kb method5: 8.03666186333 วินาที ขนาดกระบวนการ 71720 kb method6: 6.68192911148 วินาที ขนาดกระบวนการ 38240 kb
ค่อนข้างชัดเจนว่าพวก Python ทำงานได้ดีมากในการเพิ่มประสิทธิภาพการต่อสายอักขระและอย่างที่ Hoare กล่าวว่า: "การเพิ่มประสิทธิภาพก่อนกำหนดเป็นรากเหง้าของความชั่วร้ายทั้งหมด" :-)
การอาศัยการปรับแต่งคอมไพลเลอร์นั้นเปราะบาง เกณฑ์มาตรฐานที่เชื่อมโยงในคำตอบที่ยอมรับและตัวเลขที่ Antoine-tran ให้ไว้ไม่น่าเชื่อถือ แอนดรูแฮร์ทำผิดพลาดในการรวมการเรียกร้องrepr
ในวิธีการของเขา นั่นทำให้วิธีการทั้งหมดช้าลงเท่า ๆ กัน แต่บดบังโทษที่แท้จริงในการสร้างสตริง
ใช้join
. มันเร็วมากและแข็งแกร่งมากขึ้น
$ ipython3
Python 3.5.1 (default, Mar 2 2016, 03:38:02)
IPython 4.1.2 -- An enhanced Interactive Python.
In [1]: values = [str(num) for num in range(int(1e3))]
In [2]: %%timeit
...: ''.join(values)
...:
100000 loops, best of 3: 7.37 µs per loop
In [3]: %%timeit
...: result = ''
...: for value in values:
...: result += value
...:
10000 loops, best of 3: 82.8 µs per loop
In [4]: import io
In [5]: %%timeit
...: writer = io.StringIO()
...: for value in values:
...: writer.write(value)
...: writer.getvalue()
...:
10000 loops, best of 3: 81.8 µs per loop
repr
โทรเข้าครอบงำรันไทม์ แต่ไม่จำเป็นต้องทำให้ความผิดพลาดเป็นเรื่องส่วนตัว
Python มีหลายสิ่งที่ตอบสนองวัตถุประสงค์ที่คล้ายกัน:
list(your_string)
คุณยังสามารถใช้ a UserString.MutableString
สำหรับสิ่งนี้(c)StringIO.StringIO
มีประโยชน์สำหรับสิ่งที่อาจใช้ไฟล์ แต่น้อยกว่านั้นสำหรับการสร้างสตริงทั่วไปใช้วิธีที่ 5 จากด้านบน (ไฟล์ Pseudo) เราจะได้รับความสมบูรณ์แบบและความยืดหยุ่นที่ดีมาก
from cStringIO import StringIO
class StringBuilder:
_file_str = None
def __init__(self):
self._file_str = StringIO()
def Append(self, str):
self._file_str.write(str)
def __str__(self):
return self._file_str.getvalue()
ตอนนี้ใช้มัน
sb = StringBuilder()
sb.Append("Hello\n")
sb.Append("World")
print sb
ไม่มีอะนาล็อกที่ชัดเจน - ฉันคิดว่าคุณคาดว่าจะใช้การต่อสตริง (น่าจะได้รับการปรับให้เหมาะสมตามที่กล่าวไว้ก่อนหน้านี้) หรือคลาสของบุคคลที่สาม (ฉันสงสัยว่ามันมีประสิทธิภาพมากกว่ามาก - รายการใน python เป็นแบบไดนามิกจึงไม่ทำงานอย่างรวดเร็ว ถ่าน [] สำหรับบัฟเฟอร์ตามที่ฉันคิด) คลาสที่เหมือน Stringbuilder ไม่ใช่การปรับให้เหมาะสมก่อนเวลาอันควรเนื่องจากคุณลักษณะโดยกำเนิดของสตริงในหลายภาษา (ไม่เปลี่ยนรูปแบบ) ซึ่งอนุญาตให้มีการปรับให้เหมาะสมได้หลายแบบ (ตัวอย่างเช่นการอ้างอิงบัฟเฟอร์เดียวกันสำหรับชิ้นส่วน / สตริงย่อย) Stringbuilder / stringbuffer / stringstream-like คลาสทำงานได้เร็วกว่าการต่อสตริง (สร้างอ็อบเจ็กต์ชั่วคราวขนาดเล็กจำนวนมากที่ยังต้องการการจัดสรรและการรวบรวมขยะ) และแม้แต่การจัดรูปแบบสตริงเครื่องมือที่เหมือน printf โดยไม่จำเป็นต้องตีความค่าใช้จ่ายในการจัดรูปแบบรูปแบบที่ค่อนข้างใช้เวลานาน มีรูปแบบการโทรมากมาย
ในกรณีที่คุณกำลังมองหาวิธีการต่อสายอักขระที่รวดเร็วใน Python คุณไม่จำเป็นต้องมีคลาส StringBuilder พิเศษ การเชื่อมต่อแบบง่ายก็ใช้ได้เช่นกันโดยไม่มีการลงโทษด้านประสิทธิภาพที่เห็นใน C #
resultString = ""
resultString += "Append 1"
resultString += "Append 2"
ดูคำตอบของ Antoine-tranสำหรับผลลัพธ์ด้านประสิทธิภาพ