Şimdi Ara

List eklemede performans farkı

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
2 Misafir - 2 Masaüstü
5 sn
9
Cevap
0
Favori
252
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • a = [1,2,3,4]
    olarak bir list var. Aşağıdaki her iki satır da a'ya 9 ekler. Aralarında performans farkı var mıdır? Neden? Cevabinizi destekleyen kaynaklar gösteriniz.
    a += [9]
    a[4:] = [9]

    < Bu ileti mini sürüm kullanılarak atıldı >



  • Subset alarak atama yapmak daha yavaş kalır. Öncesinde listenin 4:'e karşılık gelen subsetini alıyor, onu [9] ile yer değiştiriyor, ve geri atıyor.
    += ve list tipinin kendi fonksiyonu append() daha hızlı çalışıyorlar.
    list.append() en hızlı çalışıyor.

    benim makinemde şöyleler 1000 iterasyonda şöyleler zaman bakımından (dolayısıyla kaynak deneme yanılma):
    += 0.00041727899999999263 s
    subset assignment 0.0006215100000000473 s
    append() 0.0003777419999999587 s

    daha derine inip operasyon sayısına veya tipine bakılabilir dis modülüyle çok ayrıntı gerekiyorsa eğer.
    docs.python.org
    dis — Disassembler for Python bytecode — Python 3.7.4rc2 documentation
    https://docs.python.org/3/library/dis.html




  • Hatta üşenmeyip baktım neymiş diye ben de merak ettim. f1 f2 f3 yukarıdaki aynı sırayla şöyle bytecode üretiyor:

    >>> dis.dis(f1)
    4 0 LOAD_CONST 1 (1)
    2 LOAD_CONST 2 (2)
    4 LOAD_CONST 3 (3)
    6 LOAD_CONST 4 (4)
    8 BUILD_LIST 4
    10 STORE_FAST 0 (l) (listenin adını l koymuştum)

    5 12 LOAD_FAST 0 (l)
    14 LOAD_CONST 5 (9)
    16 BUILD_LIST 1
    18 INPLACE_ADD
    20 STORE_FAST 0 (l)
    22 LOAD_CONST 0 (None)
    24 RETURN_VALUE
    >>> dis.dis(f2)
    8 0 LOAD_CONST 1 (1)
    2 LOAD_CONST 2 (2)
    4 LOAD_CONST 3 (3)
    6 LOAD_CONST 4 (4)
    8 BUILD_LIST 4
    10 STORE_FAST 0 (l)

    9 12 LOAD_FAST 0 (l)
    14 LOAD_CONST 4 (4)
    16 LOAD_CONST 0 (None)
    18 BUILD_SLICE 2
    20 DUP_TOP_TWO
    22 BINARY_SUBSCR
    24 LOAD_CONST 5 (9)
    26 BUILD_LIST 1
    28 INPLACE_ADD
    30 ROT_THREE
    32 STORE_SUBSCR
    34 LOAD_CONST 0 (None)
    36 RETURN_VALUE
    >>> dis.dis(f3)
    12 0 LOAD_CONST 1 (1)
    2 LOAD_CONST 2 (2)
    4 LOAD_CONST 3 (3)
    6 LOAD_CONST 4 (4)
    8 BUILD_LIST 4
    10 STORE_FAST 0 (l)

    13 12 LOAD_FAST 0 (l)
    14 LOAD_METHOD 0 (append)
    16 LOAD_CONST 5 (9)
    18 CALL_METHOD 1
    20 POP_TOP
    22 LOAD_CONST 0 (None)
    24 RETURN_VALUE



    < Bu mesaj bu kişi tarafından değiştirildi KaramazovX -- 10 Haziran 2019; 12:31:54 >




  • Kusurumuza bakma artık yardım etmeyi denedik. Ağız alışkanlığı, subset deyivermişim. Süreler de zaten 1000 iterasyon üzerindendi, şu da 10 milyon iterasyonlu:

    += 2.206635226 s
    slicing 3.3122043559999996 s
    append() 2.1419355849999997 s
  • şu tabloda
    docs.python.org
    Built-in Types — Python 3.7.4rc2 documentation
    https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
    s.append() için "same as s[len(s):len(s)] = [x]" demiş, ben de aslında onun aynısı s[len(s):] kullandım. slicing neden append()'e göre yavaş oluyor? biraz daha büyük listeler ve iterasyon sayılarıyla dener misin?
    mesela 1000lik liste kullan, list comprehesion ile tutabilirsin, veya döngüde kendin oluştur



    < Bu mesaj bu kişi tarafından değiştirildi seyfi84 -- 10 Haziran 2019; 12:52:46 >
    < Bu ileti mini sürüm kullanılarak atıldı >




  • Muhtemelen nasıl çalıştığını ve beklenen davranışını açıklamak adına öyle söylemişler. CPython seviyesinde daha optimize çalışması adına işleyişleri değişebiliyor metotların (f-string'ler de güya .format ile aynı işi yapıyor ama daha hızlı). Başlangıçta öyle yazılıp sonra performans için revize edilip wiki güncellenmeyi unutmuş da olabilir. Özellikle bu built-in tiplerin metotlarında falan oluyor bu. Ki zaten dis de built-in metotların bazılarını disassemble etmiyor. Tek ve atomik op olduğu için.

    S[s:e] ifadesi o slice'ı almak için aradaki basamakları itere ediyor, O(n). append() O(1) operasyon (kaynak). Sayıları artırsak hız farkı append lehine daha da açılır büyük ihtimalle cevabı attıktan sonra deneyeceğim.



    < Bu mesaj bu kişi tarafından değiştirildi KaramazovX -- 10 Haziran 2019; 13:13:10 >




  • Çoklu eleman ekliyorsak extend() kullanmak lazımdı öyle denedim. Onda çok fark olmuyor. 1000 elemanı 1000 elemanla birleştirmeye çalışınca sonuç şu (10bin tekrar):

    += 1.429600953 s
    slice 1.455506979 s
    extend() 1.4946402209999996 s

    1000 elemanlı listeye tekil eleman ekleme (100bin tekrar), bu enteresan:

    += 6.698594278000001
    slice 7.009873052
    append() 7.193749627000001

    Alınan slice'ın boyutuna göre ölçekleniyor o halde harcadığı zaman miktarı. Başka bir anlam çıkarmadım ben buradan. Senin fikrin var mı? Ve madem böyleydi wiki'de ne maksatla sabit zamanlı çalışır diyor bu adamlar?

    Bu arada bunlar foruma sınav sorusu falan mıydı neydi, ben hakkaten gerekli diye benchmark falan atıyorum da yani bildiğimden veya açıklayabileceğimden değilmiş demek ki



    < Bu mesaj bu kişi tarafından değiştirildi KaramazovX -- 10 Haziran 2019; 13:46:54 >




  • Yapay Zeka’dan İlgili Konular
    Daha Fazla Göster
    
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.