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

StringBuilderC # 과 같이 Python에 문자열 클래스가 있습니까?



답변

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

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


답변

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가 말했듯이 : “조기 최적화는 모든 악의 근원입니다.”:-)


답변

컴파일러 최적화에 의존하는 것은 취약합니다. 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


답변

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

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

답변

위의 방법 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


답변

StringIO 또는 cStringIO를 시도 할 수 있습니다.


답변

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