Neden str toplamamalısınız
Günlerden pazar, bir yandan çay içip bir yandan Python kurcalarken, aklıma döngü optimizasyon yöntemlerini denemek geldi. Daha önce bir yerde gördüğümü hatırladığım için, bir liste içindeki int'leri karaktere dönüştürüp, bir str içinde birleştirmeyi deniyorum. Bu yöntem bu kadar hızlı, şu yöntem bu kadar yavaş derken, acaba str objelerini + ile toplamak ne kadar kötü olabilir ki diye merak ettim. 1 milyon karakter ile şunu denedim:
Bekledim, bekledim, bekledim... Bir türlü bitmek bilmedi. Ben de daha küçük liste üzerinde deneyeyim dedim. Önce 10 bin, sonra 20 bin derken bir döngü içerisinde 420 bin uzunluklu listeye kadar denedim. Sonuçlar şöyle oldu:
Grafikten de görüleceği üzere, çalışma süresinin artışı biraz exponansiyel gibi görünüyor.
İlk bakışta şaşırdım, lineer bir artış bekliyordum. Sonra kafama dank etti! Döngünün
her etabında, bir önceki str'nin başka bir yere kopyalanması ve yeni karakterin eklenmesi
gerekiyor. Döngü büyüdükçe, kopyalanması gereken string sayısı ile birlikte
kopyalanan stringlerin uzunluğu da artıyor. Dolayısıyla, n * (n - 1) / 2
karakter taşıma
işlemi yapılıyor. Yani gerçekten döngünün büyüklüğü ve harcanan zaman arasında exponansiyonel kuadratik
bir ilişki var. Kabataslak bir hesap yaptım, eğer işlemin bitmesini bekleseydim, 13-14 saat
beklemem gerekecekmiş. Aynı hesapla, eğer 10 milyon karakterle işlem yapsam, 57 gün beklemem
gerekecekti. İşte bu yüzden, özellikle döngü içerisinde str toplamak çok hoş sonuçlar doğurmuyor.
Bunlar da 10 milyon karakterle denediğim diğer algoritmalar:
Sonuçlar:
for loop 1 took 4.05400013924 seconds for loop 2 took 2.70499992371 seconds map took 2.22099995613 seconds map local took 2.24699997902 seconds
Evet, şampiyonumuz:
Bu ölçümleri yapmak için kullandığım dosyaya gist üzerinden erişebilirsiniz.