Чи є якийсь клас струн у Python, як StringBuilderу C #?
Чи є якийсь клас струн у Python, як StringBuilderу C #?
Відповіді:
Не існує співвідношення один на один. По-справжньому гарну статтю див. У розділі Ефективне об'єднання рядків у Python :
Побудова довгих рядків на мові прогмінгу Python іноді може призвести до дуже повільного запущеного коду. У цій статті я досліджую обчислювальну ефективність різних методів конкатенації рядків.
Я використав код Олівера Кроу (посилання, яке надав Ендрю Заєць) і трохи адаптував його до адаптації Python 2.7.3. (за допомогою пакету timeit). Я працював на своєму персональному комп’ютері, Lenovo T61, 6 Гб оперативної пам’яті, Debian GNU / Linux 6.0.6 (стискати).
Ось результат для 10000 ітерацій:
метод1: 0,0538418292999 сек розмір процесу 4800 кб метод2: 0,22602891922 сек розмір процесу 4960 кб метод3: 0,0605459213257 сек розмір процесу 4980 кб метод4: 0,05404030666351 сек розмір процесу 5536 кб метод5: 0,051080703735 сек розмір процесу 5272 кб метод6: 0,0542731285095 сек розмір процесу 5512 кб
і для 5 000 000 ітерацій (метод 2 був ігнорований, оскільки він запускався занадто повільно, як назавжди):
метод1: 5.88603997231 сек розмір процесу 37976 кб метод3: 8.40748500824 сек розмір процесу 38024 кб метод4: 7.96380496025 сек розмір процесу 321968 кб метод5: 8.03666186333 сек розмір процесу 71720 кб метод6: 6.68192911148 сек розмір процесу 38240 кб
Цілком очевидно, що хлопці з Python зробили досить велику роботу з оптимізації конкатенації рядків, і, як сказав Хоар: "передчасна оптимізація - корінь усього зла" :-)
Покладатися на оптимізацію компілятора неміцно. Орієнтирам, пов'язаним у прийнятій відповіді, та цифри, надані Антуаном-тран, не варто вірити. Ендрю Заєць робить помилку, включаючи заклик до 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). Ви також можете використовувати UserString.MutableStringдля цього.(c)StringIO.StringIO корисно для речей, які б інакше взяли файл, але менш для загальної побудови рядків.Використовуючи метод 5 зверху (The Pseudo File), ми можемо отримати дуже хороший перф і гнучкість
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 мають динамічний тип, тому немає швидкодіючих char [] для буфера, як я припускаю). Класи, схожі на Stringbuilder, не мають передчасної оптимізації через вроджену особливість рядків на багатьох мовах (незмінність) - що дозволяє здійснити багато оптимізацій (наприклад, посилання на той самий буфер для фрагментів / підрядів). Класи Stringbuilder / stringbuffer / stringstream працюють набагато швидше, ніж об'єднання рядків (створюючи багато невеликих тимчасових об'єктів, які все ще потребують виділення та збирання сміття) і навіть форматування рядків інструментів, схожих на printf, не потребують інтерпретації накладних форм форматування, які досить затратні для багато форматних дзвінків.
Якщо ви шукаєте тут метод швидкого з'єднання рядків у Python, то вам не потрібен спеціальний клас StringBuilder. Просте конкатенація працює так само без покарання за ефективність, яке бачимо на C #.
resultString = ""
resultString += "Append 1"
resultString += "Append 2"
Дивіться відповідь Антуана-тран за результатами роботи