Python'da StringBuilderC # gibi bir string sınıfı var mı ?
Python'da StringBuilderC # gibi bir string sınıfı var mı ?
Yanıtlar:
Bire bir korelasyon yoktur. Gerçekten iyi bir makale için lütfen Python'da Efficient String Concatenation'a bakın :
Python programlama dilinde uzun dizeler oluşturmak bazen kodun çok yavaş çalışmasına neden olabilir. Bu makalede, çeşitli dizi birleştirme yöntemlerinin hesaplama performansını araştırıyorum.
Oliver Crow kodunu (Andrew Hare tarafından verilen bağlantı) kullandım ve Python 2.7.3'ü uyarlamak için biraz uyarladım. (timeit paketini kullanarak). Kişisel bilgisayarımda koştum, Lenovo T61, 6GB RAM, Debian GNU / Linux 6.0.6 (sıkıştır).
İşte 10.000 yinelemenin sonucu:
method1: 0,0538418292999 saniye işlem boyutu 4800 kb method2: 0,22602891922 saniye işlem boyutu 4960 kb method3: 0,0605459213257 saniye işlem boyutu 4980 kb method4: 0,0544030666351 saniye işlem boyutu 5536 kb method5: 0,0551080703735 saniye işlem boyutu 5272 kb method6: 0,0542731285095 saniye işlem boyutu 5512 kb
ve 5.000.000 yineleme için (yöntem 2, sonsuza kadar olduğu gibi çok yavaş çalıştığı için göz ardı edildi):
yöntem1: 5,88603997231 saniye işlem boyutu 37976 kb method3: 8.40748500824 saniye işlem boyutu 38024 kb method4: 7.96380496025 saniye işlem boyutu 321968 kb method5: 8.03666186333 saniye işlem boyutu 71720 kb method6: 6.68192911148 saniye işlem boyutu 38240 kb
Python adamlarının dize birleştirmeyi optimize etmek için oldukça iyi bir iş çıkardığı oldukça açıktır ve Hoare'nin dediği gibi: "erken optimizasyon tüm kötülüklerin köküdür" :-)
Derleyici optimizasyonlarına güvenmek kırılgandır. Kabul edilen cevapta ve Antoine-tran tarafından verilen sayılarda bağlantılı kriterlere güvenilmeyecektir. Andrew Hare repr, yöntemlerine bir çağrı da dahil etme hatasını yapar . Bu, tüm yöntemleri eşit derecede yavaşlatır, ancak dizeyi oluştururken gerçek cezayı gizler.
Kullanın join. Çok hızlı ve daha sağlam.
$ 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çağrı çalışma süresine hakimdir, ancak hatayı kişiselleştirmeye gerek yoktur.
Python, benzer amaçları yerine getiren birkaç şeye sahiptir:
list(your_string). Bunun için de kullanabilirsiniz UserString.MutableString.(c)StringIO.StringIO aksi takdirde dosya alacak şeyler için kullanışlıdır, ancak genel dizgi oluşturma için daha azdır.Yukarıdaki yöntem 5'i (Sözde Dosya) kullanarak çok iyi performans ve esneklik elde edebiliriz
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()
şimdi kullanıyorum
sb = StringBuilder()
sb.Append("Hello\n")
sb.Append("World")
print sb
StringIO veya cStringIO'yu deneyebilirsiniz
Açık bir analog yok - bence dizi birleştirmeleri (muhtemelen daha önce söylendiği gibi optimize edilmiş) veya üçüncü taraf sınıf (çok daha verimli olduklarından şüpheliyim) kullanmanız bekleniyor - python'daki listeler dinamik tipte olduğundan hızlı çalışma yok sandığım gibi arabellek için char []). Stringbuilder benzeri sınıflar, birçok dildeki dizelerin doğuştan gelen özelliği (değişmezlik) nedeniyle erken optimizasyon değildir - bu birçok optimizasyona izin verir (örneğin, dilimler / alt dizeler için aynı arabelleğe başvurma). Stringbuilder / stringbuffer / stringstream benzeri sınıflar, dizeleri birleştirmekten çok daha hızlı çalışır (hala ayırmalara ve çöp toplamaya ihtiyaç duyan birçok küçük geçici nesneler üretir) ve hatta printf benzeri araçları dize biçimlendirir; birçok format çağrısı.
Python'da hızlı bir dizgi birleştirme yöntemi arıyorsanız, o zaman özel bir StringBuilder sınıfına ihtiyacınız yoktur. Basit birleştirme, C # 'da görülen performans cezası olmadan da aynı şekilde çalışır.
resultString = ""
resultString += "Append 1"
resultString += "Append 2"
Bkz Antoine-Tran cevabı performans sonuçları için