C #의 StringBuilder와 같은 Python 문자열 클래스?


답변:


102

일대일 상관 관계가 없습니다. 정말 좋은 기사를 보려면 Python의 효율적인 문자열 연결을 참조하십시오 .

Python 프로그래밍 언어로 긴 문자열을 작성하면 코드 실행 속도가 매우 느려질 수 있습니다. 이 기사에서는 다양한 문자열 연결 방법의 계산 성능을 조사합니다.


27
이 기사는 Python 2.2를 기반으로 작성되었습니다. 테스트는 최신 버전의 Python에서 다소 다르게 나올 수 있으며 (CPython은 일반적으로 연결을 성공적으로 최적화하지만 중요한 코드에서는 이에 의존하고 싶지 않습니다.) 목록 이해를 사용하는 생성기 표현식은 고려할 가치가 있습니다. .
Mike Graham

4
(링크 부패 문제를 피하기 위해) 적어도 몇 가지 구현에서 그 기사에서 몇 가지 주요 사항을 가져 오는 것이 좋습니다.
jpmc26

3
방법 1 : resultString + = appendString은 아래 @ Antoine-tran의 테스트에 따라 가장 빠릅니다
Justas

5
귀하의 견적이 질문에 전혀 대답하지 않습니다. 새로운 지침을 준수하기 위해 답변 자체에 관련 부분을 포함하십시오.
기금 모니카의 소송

27

Oliver Crow (Andrew Hare가 제공 한 링크)의 코드를 사용하고 Python 2.7.3을 조정하기 위해 약간 수정했습니다. (timeit 패키지 사용). 개인용 컴퓨터 인 Lenovo T61, 6GB RAM, Debian GNU / Linux 6.0.6 (squeeze)에서 실행했습니다.

다음은 10,000 회 반복에 대한 결과입니다.

method1 : 0.0538418292999 초
프로세스 크기 4800kb
method2 : 0.22602891922 초
프로세스 크기 4960 kb
method3 : 0.0605459213257 초
프로세스 크기 4980kb
method4 : 0.0544030666351 초
프로세스 크기 5536 kb
method5 : 0.0551080703735 초
프로세스 크기 5272 kb
method6 : 0.0542731285095 초
프로세스 크기 5512kb

5,000,000 회 반복 (영원히 너무 느리게 실행 되었기 때문에 메서드 2는 무시되었습니다) :

method1 : 5.88603997231 초
프로세스 크기 37976 kb
method3 : 8.40748500824 초
프로세스 크기 38024 kb
method4 : 7.96380496025 초
프로세스 크기 321968 kb
method5 : 8.03666186333 초
프로세스 크기 71720 kb
method6 : 6.68192911148 초
프로세스 크기 38240 kb

파이썬 사람들이 문자열 연결을 최적화하기 위해 꽤 훌륭한 일을했다는 것은 분명합니다. 그리고 Hoare가 말했듯이 : "조기 최적화는 모든 악의 근원입니다.":-)


2
분명히 Hoare는 그것을 받아들이지 않습니다 : hans.gerwitz.com/2004/08/12/…
Pimin Konstantin Kefaloukos

5
깨지기 쉬운 인터프리터 의존적 최적화를 피하는 것은 조기 최적화가 아닙니다. PyPy로 이식하거나 최적화를 위해 많은 미묘한 실패 사례 중 하나에 부딪 힐 위험이 있다면 올바른 방법으로 작업하십시오.
Veedrac 2014

1
컴파일러가 최적화하는 것이 방법 1이 더 쉬운 것 같습니다.
mbomb007 2015

25

컴파일러 최적화에 의존하는 것은 취약합니다. Antoine-tran이 제공하는 허용 된 답변과 숫자에 연결된 벤치 마크는 신뢰할 수 없습니다. Andrew Hare는 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호출이 런타임을 지배하지만 실수를 개인적으로 만들 필요는 없습니다.
Alex Reinking

3
@AlexReinking 죄송합니다, 개인적인 의미는 없습니다. 무엇이 개인적이라고 생각했는지 잘 모르겠습니다. 그러나 이름을 사용하는 경우 사용자의 답변을 참조하기 위해서만 사용했습니다 (사용자 이름과 일치하지만 더 좋은 방법이 있는지 확실하지 않음).
GrantJ

1
데이터 초기화와 연결 작업을 분리하는 좋은 타이밍 예
aiodintsov

19

파이썬에는 비슷한 목적을 수행하는 몇 가지가 있습니다.

  • 조각에서 큰 문자열을 만드는 일반적인 방법 중 하나는 문자열 목록을 늘리고 완료되면 결합하는 것입니다. 이것은 자주 사용되는 Python 관용구입니다.
    • 데이터를 형식화와 통합하는 문자열을 작성하려면 형식화를 별도로 수행해야합니다.
  • 문자 수준에서 삽입 및 삭제하려면 길이가 1 인 문자열 목록을 유지합니다. (문자열로 만들려면을 호출 list(your_string)합니다. UserString.MutableString이를 위해 a 를 사용할 수도 있습니다 .
  • (c)StringIO.StringIO 그렇지 않으면 파일을 가져 오는 것에 유용하지만 일반적인 문자열 작성에는 덜 유용합니다.

10

위의 방법 5 (의사 파일)를 사용하면 매우 우수한 성능과 유연성을 얻을 수 있습니다.

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


-1

명시적인 아날로그는 없습니다-문자열 연결 (이전에 말했듯이 최적화되었을 가능성이 있음) 또는 타사 클래스 (훨씬 더 효율적이라는 것은 의심 스러움)를 사용해야한다고 생각합니다. 파이썬의 목록은 동적 형식이므로 빠르게 작동하지 않습니다. 내가 가정하는 버퍼에 대한 char []). Stringbuilder와 유사한 클래스는 많은 언어 (불변성)에서 문자열의 고유 한 기능으로 인해 조기 최적화가 아닙니다. 이는 많은 최적화를 허용합니다 (예 : 슬라이스 / 하위 문자열에 대해 동일한 버퍼 참조). Stringbuilder / stringbuffer / stringstream과 같은 클래스는 문자열을 연결하는 것 (할당과 가비지 수집이 여전히 필요한 많은 작은 임시 객체를 생성)과 문자열 형식화 printf와 같은 도구보다 훨씬 빠르게 작동합니다. 많은 포맷 호출.


-4

파이썬에서 빠른 문자열 연결 방법을 찾고 있다면 특별한 StringBuilder 클래스가 필요하지 않습니다. 간단한 연결은 C #에서 볼 수있는 성능 저하없이 잘 작동합니다.

resultString = ""

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

성능 결과는 Antoine-tran의 답변 을 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.