2010-03-10 27 views
70

Có một số lớp chuỗi trong Python như StringBuilder trong C#?Lớp chuỗi Python như StringBuilder trong C#?

+1

Đây là bản sao của [Tương đương Python của Java StringBuffer] (https://stackoverflow.com/questions/19926089/python-equivalent-of-java-stringbuffer). ** THẬN TRỌNG: Câu trả lời ở đây là lạc hậu và có, trên thực tế, trở nên gây hiểu nhầm. ** Xem [câu hỏi khác] (https://stackoverflow.com/questions/19926089/python-equivalent-of-java- stringbuffer) cho các câu trả lời phù hợp hơn với các phiên bản Python hiện đại (chắc chắn là 2.7 trở lên). –

Trả lời

58

Không có one-to-one tương quan. Đối với một bài viết thực sự tốt xin vui lòng xem Efficient String Concatenation in Python:

Xây dựng chuỗi dài bằng ngôn ngữ Python progamming có thể đôi khi kết quả trong mã chạy rất chậm. Trong bài viết này tôi điều tra hiệu suất tính toán tính toán khác nhau của phương pháp nối chuỗi khác nhau.

+14

Lưu ý rằng bài viết này được viết dựa trên Python 2.2. Các bài kiểm tra có thể sẽ xuất hiện hơi khác trong phiên bản hiện đại của Python (CPython thường tối ưu hóa thành công nối, nhưng bạn không muốn phụ thuộc vào điều này trong mã quan trọng) và biểu thức máy phát mà anh ta sử dụng khả năng hiểu danh sách sẽ đáng xem xét . –

+3

Nó sẽ là tốt để kéo trong một số điểm nổi bật trong bài viết đó, ít nhất một vài triển khai (để tránh các vấn đề liên kết thối). – jpmc26

+3

Phương pháp 1: resultString + = appendString là nhanh nhất theo các bài kiểm tra của @ Antoine-tran bên dưới – Justas

4

bạn có thể thử StringIO hoặc cStringIO

+2

FYI Hiện tại, không có liên kết nào đang hoạt động –

+0

Họ hiện đang hoạt động! –

12

Python có một vài điều mà thực hiện mục đích tương tự:

  • Một cách phổ biến để xây dựng chuỗi lớn từ mảnh là để phát triển một danh sách các chuỗi và tham gia nó khi bạn đang thực hiện. Đây là một thành ngữ Python thường được sử dụng.
    • Để tạo chuỗi kết hợp dữ liệu với định dạng, bạn sẽ thực hiện định dạng riêng.
  • Để chèn và xóa ở cấp độ ký tự, bạn sẽ giữ danh sách các chuỗi có độ dài một. (Để làm điều này từ một chuỗi, bạn muốn gọi list(your_string). Bạn cũng có thể sử dụng một UserString.MutableString cho việc này.
  • (c)StringIO.StringIO rất hữu ích cho những thứ mà nếu không sẽ mất một tập tin, nhưng ít để xây dựng chuỗi chung.
23

Tôi đã sử dụng mã của Oliver Crow (liên kết do Andrew Hare đưa ra) và điều chỉnh nó một chút để điều chỉnh Python 2.7.3 (bằng cách sử dụng gói thời gian) .Tôi chạy trên máy tính cá nhân của mình, Lenovo T61, RAM 6 GB, Debian GNU/Linux 6.0.6 (squeeze)

Đây là kết quả cho 10.000 lần lặp lại:

 
method1: 0.0538418292999 secs 
process size 4800 kb 
method2: 0.22602891922 secs 
process size 4960 kb 
method3: 0.0605459213257 secs 
process size 4980 kb 
method4: 0.0544030666351 secs 
process size 5536 kb 
method5: 0.0551080703735 secs 
process size 5272 kb 
method6: 0.0542731285095 secs 
process size 5512 kb 

và cho 5.000.000 lặp (phương pháp 2 đã bị bỏ qua vì nó chạy tooo chậm, giống như mãi mãi):

 
method1: 5.88603997231 secs 
process size 37976 kb 
method3: 8.40748500824 secs 
process size 38024 kb 
method4: 7.96380496025 secs 
process size 321968 kb 
method5: 8.03666186333 secs 
process size 71720 kb 
method6: 6.68192911148 secs 
process size 38240 kb 

Nó là khá rõ ràng rằng Python kẻ đã làm việc khá tuyệt vời để tối ưu hóa chuỗi nối, và như Hoare nói: "sớm tối ưu hóa là gốc rễ của mọi tội lỗi" :-)

+1

Rõ ràng Hoare không chấp nhận rằng: http://hans.gerwitz.com/2004/08/12/premature-optimization-is-the-root-of-all-evil.html –

+2

Nó không phải là một tối ưu hóa sớm để tránh sự tối ưu hóa phụ thuộc vào mong muốn, thông dịch viên. Nếu bạn muốn chuyển sang PyPy hoặc có nguy cơ đánh trúng [một trong nhiều trường hợp lỗi tinh tế] (http://stackoverflow.com/questions/24040198/cpython-string-addition-optimisation-failure-case) để tối ưu hóa, hãy làm những điều đúng cách. – Veedrac

+0

Có vẻ như Phương pháp 1 dễ dàng hơn cho trình biên dịch để tối ưu hóa. – mbomb007

8

Sử dụng phương pháp 5 từ trên cao (The Pseudo tập tin), chúng tôi có thể nhận được perf rất tốt và linh hoạt

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() 

tại sử dụng nó

sb = StringBuilder() 

sb.Append("Hello\n") 
sb.Append("World") 

print sb 
-1

Trong trường hợp bạn đang ở đây tìm kiếm một phương pháp nối chuỗi nhanh bằng Python, sau đó bạn không cần một lớp StringBuilder đặc biệt. Ghép nối đơn giản cũng hoạt động tốt mà không có hình phạt hiệu suất được thấy trong C#.

resultString = "" 

resultString += "Append 1" 
resultString += "Append 2" 

Xem Antoine-tran's answer cho kết quả hiệu suất

5

Dựa vào tối ưu hóa trình biên dịch là mong manh. Các tiêu chuẩn được liên kết trong câu trả lời và số được chấp nhận bởi Antoine-tran không được tin cậy. Andrew Hare phạm sai lầm bao gồm một cuộc gọi đến repr trong các phương pháp của mình. Điều đó làm chậm tất cả các phương thức như nhau nhưng che khuất hình phạt thực sự trong việc xây dựng chuỗi.

Sử dụng join. Nó rất nhanh và mạnh mẽ hơn.

$ 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 
0

Không có tương tự rõ ràng - tôi nghĩ rằng bạn đang dự kiến ​​sẽ sử dụng concatenations chuỗi (có khả năng tối ưu hóa như đã nói trước đó) hoặc đẳng cấp của bên thứ ba (tôi nghi ngờ rằng họ rất nhiều hiệu quả hơn - danh sách trong python là năng động -typed vì vậy không có char nhanh chóng làm việc [] cho bộ đệm như tôi giả định). Các lớp giống như Stringbuilder không được tối ưu hóa sớm vì tính năng bẩm sinh của các chuỗi trong nhiều ngôn ngữ (bất biến) - cho phép nhiều tối ưu hóa (ví dụ, tham chiếu cùng một bộ đệm cho các slice/substrings). Các lớp Stringbuilder/stringbuffer/stringstream giống làm việc nhanh hơn nhiều so với các chuỗi nối (tạo ra nhiều đối tượng tạm thời nhỏ vẫn cần phân bổ và thu gom rác) và thậm chí các công cụ giống như các công cụ in giống như chuỗi, không cần phải giải thích. cho nhiều cuộc gọi định dạng.

Các vấn đề liên quan