Эффективное хранение структур в Python
От: meandr  
Дата: 22.09.09 21:02
Оценка:
Hello, All!

Существуют ли в питоне каке либо средства или библиотеки позволяющие сохранять структуры (подобные c++ структурам) более эффективно (по памяти) нежели представление их через словари? (dict)

Ситуация в общем такая у меня есть список (list) структур содержащих в свою очередь несколько вложенных структур. При 100.000 элементах в списке python потребляет 400MB памяти. Мажно ли как нибудь это потребление уменьшить?
Posted via RSDN NNTP Server 2.1 beta
Re: Эффективное хранение структур в Python
От: Critical Error ICQ: 123736611
Дата: 23.09.09 00:20
Оценка:
Здравствуйте, meandr, Вы писали:

M>Hello, All!


M>Существуют ли в питоне каке либо средства или библиотеки позволяющие сохранять структуры (подобные c++ структурам) более эффективно (по памяти) нежели представление их через словари? (dict)


M>Ситуация в общем такая у меня есть список (list) структур содержащих в свою очередь несколько вложенных структур. При 100.000 элементах в списке python потребляет 400MB памяти. Мажно ли как нибудь это потребление уменьшить?


Есть стандартный модуль struct — он позволяет создавать структуры из элементов любого типа. Есть еще модуль array, который позволяет создавать массивы только определенного типа.

Вот решил сам ознакомиться с данным вопросом, написал простой тест. Размещаем 100к структур из 20 случайных целых чисел в tuple, struct, array, смотрим на разницу. Тестировал на Python 2.5.

test100k.py:
from time import sleep
from struct import pack
from random import randint
from array import array

def testTuple():
    return [tuple((randint(0,100000) for j in xrange(0,20))) for i in xrange(0, 100000)]
    
format = "i"*20
def testStruct():
    return [pack(format, *[randint(0,100000) for j in xrange(0,20)]) for i in xrange(0, 100000)]

def testArray():
    return [array("i", [randint(0,100000) for j in xrange(0,20)]) for i in xrange(0, 100000)]

sleep(3)
l = testTuple() # 41 Mb
#l = testStruct() # 14 Mb
#l = testArray() # 16 Mb
sleep(3)


Результат:

testTuple:  41 Mb
testStruct: 14 Mb
testArray:  16 Mb
Массив указателей на 80-байтные структуры на C++ занял бы (80 + 4)*100000 = 8400000 = 8.2Mb
Re[2]: Эффективное хранение структур в Python
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.09.09 02:49
Оценка:
Здравствуйте, Critical Error, Вы писали:

CE>Массив указателей на 80-байтные структуры на C++ занял бы (80 + 4)*100000 = 8400000 = 8.2Mb


Забыл про служебные данные в куче, еще где-то мега полтора.
Re[2]: Эффективное хранение структур в Python
От: meandr  
Дата: 23.09.09 06:48
Оценка:
Re: Эффективное хранение структур в Python

Я наверное плохо выразился я хучу эфективно хранить нечто вроде такого:


    "id":10, 
    "res":{
      "time":0.0,
      "cur":
      {
        "field0":{
          "productivity" : 10,
          "store" : 600,
          "amount" : 20,
          "amountprev": 400,
          "producer": "iron"
        },
        "field1":{
          "productivity" : 10,
          "store" : 600,
          "amount" : 20,
          "amountprev": 400,
          "producer": "iron"
        },
        "fields2":{
          "productivity" : 10,
          "store" : 600,
          "amount" : 20,
          "amountprev": 400,
          "producer": "iron"
        },
        "fields3":{
          "productivity" : 10,
          "store" : 600,
          "amount" : 20,
          "amountprev": 400,
          "producer": "iron"
        },
      }
    },
    "builds":{
      "main1" : {
        "level" : 1,
        "state":2
      },
      "main2" : {
        "level" : 1, 
        "state":2
      },
      "main3" : {
        "level" : 1, 
        "state":2
      },
      "main4" : {
        "level" : 1, 
        "state":2
      },
      "main5" : {
        "level" : 1, 
        "state":2
      },
      "main5" : {
        "level" : 1, 
        "state":2
      },
      "main7" : {
        "level" : 1, 
        "store": 9000, 
        "getenergy" : 800,
        "state":2
      }
    },
    "tech":{
      "fly1" : {
        "level":1,
        "state":2
      },
      "fly2" : {
        "level":1,
        "state":2
      },
      "fly3" : {
        "level":1,
        "state":2
      },
      "fly4" : {
        "level":1,
        "state":2
      },      
      "fly5" : {
        "level":1,
        "state":2
      },      
      "fly6" : {
        "level":1,
        "state":2
      }
    }}
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Эффективное хранение структур в Python
От: c-smile Канада http://terrainformatica.com
Дата: 27.09.09 04:21
Оценка:
Здравствуйте, meandr, Вы писали:

M>Re: Эффективное хранение структур в Python


M>Я наверное плохо выразился я хучу эфективно хранить нечто вроде такого:


Я для такого рода просто встроил persistence в язык и VM (tiscript).
Т.е. корень таких данных можно присвоить в Storage.root и они автомагически будут вытесняться из heap в storage прозрачно для тебя (в цикле GC сборки). Т.е. в heap будут реально только
фрагменты полного дерева. Плюс еще можно Index использовать за для эффективного поиска по ключам.

Я все это к тому что сильно твоя лохматая структура не упакуется.
Т.е. я думаю что в Python тебе имеет смысл смотреть в сторону DB, а в частности OODB какой.
Re[3]: Эффективное хранение структур в Python
От: BulatZiganshin  
Дата: 29.09.09 04:25
Оценка:
Здравствуйте, meandr, Вы писали:

M>Я наверное плохо выразился я хучу эфективно хранить нечто вроде такого:


как дурацикй, но всё же работающий вариант — вычисляй хеш от ключа и храни всё это в массиве
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Эффективное хранение структур в Python
От: _jw Россия mirantis.com
Дата: 01.10.09 14:17
Оценка: 1 (1) +1
Здравствуйте, meandr, Вы писали:

M>Re: Эффективное хранение структур в Python


M>Я наверное плохо выразился я хучу эфективно хранить нечто вроде такого:


M>

M>    "id":10, 
M>    "res":{
M>      "time":0.0,
M>      "cur":
M>      {
M>


Возможно, __slots__ вам немного поможет
Re[4]: Эффективное хранение структур в Python
От: Critical Error ICQ: 123736611
Дата: 01.10.09 21:41
Оценка:
Здравствуйте, _jw, Вы писали:

_jw>Здравствуйте, meandr, Вы писали:


M>>Re: Эффективное хранение структур в Python


M>>Я наверное плохо выразился я хучу эфективно хранить нечто вроде такого:


M>>

M>>    "id":10, 
M>>    "res":{
M>>      "time":0.0,
M>>      "cur":
M>>      {
M>>


_jw>Возможно, __slots__ вам немного поможет


Да, спасибо за наводку, __slots__ действительно помогает во многих ситуациях.

Вот тест:

class Test2(object):
    def __init__(self):
        self.somefield0 = randint(0,100000)
        self.somefield1 = randint(0,100000)
        self.somefield2 = randint(0,100000)
        self.somefield3 = randint(0,100000)
        self.somefield4 = randint(0,100000)
        self.somefield5 = randint(0,100000)
        self.somefield6 = randint(0,100000)
        self.somefield7 = randint(0,100000)
        self.somefield8 = randint(0,100000)
        self.somefield9 = randint(0,100000)

class Test3(object):
    __slots__ = ('somefield0', 'somefield1', 'somefield2', 'somefield3', 'somefield4', 'somefield5', 'somefield6', 'somefield7', 'somefield8', 'somefield9')
    def __init__(self):
        self.somefield0 = randint(0,100000)
        self.somefield1 = randint(0,100000)
        self.somefield2 = randint(0,100000)
        self.somefield3 = randint(0,100000)
        self.somefield4 = randint(0,100000)
        self.somefield5 = randint(0,100000)
        self.somefield6 = randint(0,100000)
        self.somefield7 = randint(0,100000)
        self.somefield8 = randint(0,100000)
        self.somefield9 = randint(0,100000)

def testClass2():
    return [Test2() for i in xrange(0, 200000)]

def testClass3():
    return [Test3() for i in xrange(0, 200000)]


Результат:
testClass2: 144 Mb
testClass3: 42 Mb


То есть мы избавились от dict на каждый инстанс класса и получили за счет этого выигрыш по памяти. Но вариант struct 16Mb все же его обходит.
Re[5]: Эффективное хранение структур в Python
От: meandr  
Дата: 13.10.09 09:46
Оценка:
Re[4]: Эффективное хранение структур в Python
Решил проблему самописным типом для Python на C++ Экономия довольно ощутимая получилась
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.