SORU
26 AĞUSTOS 2009, ÇARŞAMBA


Sözlük vs ve neden?daha verimli olan Nesne

Ne bellek kullanımı ve CPU tüketimi açısından Python ile daha verimli bir Sözlüğü ya da Nesne?

Arka plan: Python içine veri büyük miktarda yük var. Alan bir konteyner için sadece bir nesne oluşturdum. 4M örnekleri oluşturma ve bir sözlük içine koyarak 10 dakika ve bellek ~6 GB aldı. Sözlük hazır olduktan sonra, erişim, göz açıp kapayıncaya kadar.

Örnek: Performansını kontrol etmek için aynı şeyi iki basit programlar yazdım - bir nesne, diğer sözlük kullanıyor:

Nesne (~18sec yürütme süresi):

class Obj(object):
  def __init__(self, i):
    self.i = i
    self.l = []
all = {}
for i in range(1000000):
  all[i] = Obj(i)

Sözlük (~12sec zaman yürütme):

all = {}
for i in range(1000000):
  o = {}
  o['i'] = i
  o['l'] = []
  all[i] = o

Soru: Yanlış bir şey yapıyor veya sözlük sadece daha hızlı nesne daha olur muyum? Eğer gerçekten sözlük daha iyi yapar, birisi açıklayabilir mi?

CEVAP
26 AĞUSTOS 2009, ÇARŞAMBA


__slots__ kullanarak denediniz mi?

Belgeleri http://docs.python.org/reference/datamodel.html#slots:

"Varsayılan olarak, eski ve yeni tarzı hem sınıfları öznitelik depolama için bir sözlük var. Bu nesneler çok az örnek değişkenleri olması için alan kaybına yol açar. Uzay tüketimi örnekleri çok sayıda oluştururken akut hale gelebilir.

Varsayılan yeni tarzı bir sınıf tanımı __slots__ tanımlayarak kılınabilir. __slots__ bildirimi her örneği örnek değişkenler ve saklı bir dizi sadece yeterli alan her değişken için bir değer alır. Alanı __dict__ her örnek için oluşturulmadı çünkü kaydedilir."

Bu sefer hafıza olarak kayıt ediyor mu?

Bilgisayarımda üç yaklaşımlarının karşılaştırılması:

test_slots.py:

class Obj(object):
  __slots__ = ('i', 'l')
  def __init__(self, i):
    self.i = i
    self.l = []
all = {}
for i in range(1000000):
  all[i] = Obj(i)

test_obj.py:

class Obj(object):
  def __init__(self, i):
    self.i = i
    self.l = []
all = {}
for i in range(1000000):
  all[i] = Obj(i)

test_dict.py:

all = {}
for i in range(1000000):
  o = {}
  o['i'] = i
  o['l'] = []
  all[i] = o

test_namedtuple.py (2.6) destekledi:

import collections

Obj = collections.namedtuple('Obj', 'i l')

all = {}
for i in range(1000000):
  all[i] = Obj(i, [])

Çalıştırmak kriter (CPython 2.5 kullanarak):

$ lshw | grep product | head -n 1
          product: Intel(R) Pentium(R) M processor 1.60GHz
$ python --version
Python 2.5
$ time python test_obj.py && time python test_dict.py && time python test_slots.py 

real    0m27.398s (using 'normal' object)
real    0m16.747s (using __dict__)
real    0m11.777s (using __slots__)

CPython adlı dizi test de dahil olmak üzere 2.6.2 kullanma:

$ python --version
Python 2.6.2
$ time python test_obj.py && time python test_dict.py && time python test_slots.py && time python test_namedtuple.py 

real    0m27.197s (using 'normal' object)
real    0m17.657s (using __dict__)
real    0m12.249s (using __slots__)
real    0m12.262s (using namedtuple)

Yani Evet pek sürpriz), __slots__ kullanarak hızlı başlamanıza yardımcı olur. Adlı bir başlık kullanarak __slots__ benzer performansa sahiptir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • BurnedInDotCom

    BurnedInDotC

    3 NİSAN 2010
  • hockeywebcasts

    hockeywebcas

    31 EKİM 2012
  • Jared Busch

    Jared Busch

    25 Mayıs 2011