LINUX.ORG.RU
ФорумTalks

О прожорливости питона


0

4

Довольно часто приходится читать про его аппетит и что только Java уделывает и etc. Хотелось бы услышать реальные причины прожоривости питона, в котором его обвиняют. Хотя наверняка сейчас сюда набежит голодная публика

★★★★★
Ответ на: комментарий от tailgunner

Нифига. range() тоже создает список. Получается список создается 2 раза.

different_thing
()
Ответ на: комментарий от michwill

>Пример Вам уже показали: 100000000 указателей на объект 1: [1]*100000000 (посмотрите top).

Зачем мне 1e8 ссылок на один объект? Пройди циклом по ссылкам и присвой каждой разное значение. Получишь >2gb съеденой памяти. Код я выше уже приводил.

elverion
()
Ответ на: комментарий от different_thing

Тут надо xrange использовать

>>> xrange
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined

>>> range(10)
range(0, 10)

Тред ты похоже не читал.

elverion
()
Ответ на: комментарий от elverion

хотя в C это съедало всего 400 мб.

Странно, но в питоне тот же самый результат.

Python 2.7.1 (r271:86832, Apr 15 2011, 12:11:58) 
[GCC 4.5.2 20110127 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import array
>>> a = array.array('l', xrange(100000000))
>>> a[10]
10
>>> a[100]
100
>>>

408368 394580 pts/2 S+ 18:22 1:30 python

baverman ★★★
()
Ответ на: комментарий от baverman

Вот незадача, для ссылок не работает.

>>> test = []
>>> import array
>>> a = array.array(test, range(100))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be a unicode character, not list
elverion
()
Ответ на: комментарий от elverion

Вот незадача, для ссылок не работает.

Сначала, прочитай маны, а потом уже пытайся быдлокодить, ага?

baverman ★★★
()
Ответ на: комментарий от tailgunner

Можно взять не 1e8, а 1e6. Это более реально.

Вот от с такого вот кода «l = [[] for i in range(1000000)]» питон отъел 86 mb (хотя данных там на 8mb).

elverion
()
Ответ на: комментарий от elverion

Неа, не читал. Вообще за чужим компом сижу и меня периодически сгоняют

different_thing
()
Ответ на: комментарий от elverion

> Можно взять не 1e8, а 1e6. Это более реально.

Еще раз - зачем тебе _объекты_? Речь изначально шла о массиве (списке).

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Речь изначально шла о массиве (списке).

Речь изначально шла о том что питон жрет больше чем C. Примеров — две страницы, но защитников питона они не устраивают.

elverion
()
Ответ на: комментарий от elverion

> Речь изначально шла о том что питон жрет больше чем C

Лол. А чё тут спорить? Аналоги на С можно приводить только чтобы понять, на сколько больше он жрет

different_thing
()
Ответ на: комментарий от elverion

> Речь изначально шла о том что питон жрет больше чем C.

...причем доказывалось это совершенно некорректным и безграмотным примером.

Примеров — две страницы, но защитников питона они не устраивают.

Они не устраивают любого, кто знает Питон.

tailgunner ★★★★★
()
Ответ на: комментарий от elverion

Речь изначально шла о том что питон жрет больше чем C.

ORLY?

Он под каждый integer выделяет сишную структуру со всякой дополнительной информацией типа счетчиков ссылок. Я пробовал выделять список на 100000000 элементов, так питон в OOM вылетал (при 4г виртуальной памяти), хотя в C это съедало всего 400 мб.

Изначально забурлило отсюда. Как выяснилось — это полное 4.2. Что ты как баба заюлил? Будь мужиком.

baverman ★★★
()
Ответ на: комментарий от tailgunner

Они не устраивают любого, кто знает Питон.

Ну еще бы, ведь они выставляют питон не в лучшем свете.

...причем доказывалось это совершенно некорректным и безграмотным примером.

Некорректным? Тогда исправь этот пример, чтобы он жрал не 400mb, а хотя бы 50 (в C++ все это весило бы мегабайт 8, но на такое Питон уж точно неспособен):

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b

s = 1000000
l = [1] * s
for i in range(s):
    l.append(A(i, i + 1))

input()
elverion
()
Ответ на: комментарий от baverman

>Как выяснилось — это полное 4.2.

Где 4.2? Это защитники питона с натяжкой смогли оптимизировать мой пример, и то только для частного случая целых чисел. Вопрос про аналог array для ссылок остается в силе.

elverion
()
Ответ на: комментарий от elverion

Где 4.2?

Я показал как в питоне зааллокейтить массив лонгов, чтобы он занимал столько же как и в «Си», что тебе не нравится?

Вопрос про аналог array для ссылок остается в силе.

А никто и не распинался, что питон расчудесен. Ты слышишь невидимые голоса, хочешь поговорить об этом?

baverman ★★★
()
Ответ на: комментарий от baverman

Если хранить указатели, а объекты создавать на хипе получилось 46. Если же хранить сами объекты то будет ровно 8. Не говоря уже о том что есть огромный простор для оптимизации варианта с указателями, скажем воспользоваться аллокатором из книги Александреску. Что там можно оптимизировать в Питоне я не представляю.

elverion
()
Ответ на: комментарий от baverman

>Я показал как в питоне зааллокейтить массив лонгов, чтобы он занимал столько же как и в «Си», что тебе не нравится?

Спасибо, я знаю про numpy и array. Пример был нужен чтобы показать огромный оверхед list'а, что я думаю мне удалось. Ну и похоже что для ссылок array не годится.

А никто и не распинался, что питон расчудесен.

ТС просил пруфов что Питон жручий — я их привёл.

elverion
()
Ответ на: комментарий от elverion

46 это при хранении в аналогичной (полностью аналогичной) list'у структуре?

Что там можно оптимизировать в Питоне я не представляю.

Можно как-то так:

import array

class A(object):
    __slots__ = ['data']

    def __init__(self, a, b):
        self.data = array.array('l', (a, b))
    
    @property
    def a(self):
        return self.data[0]

    @property
    def b(self):
        return self.data[1]


s = 1000000
l = []
for i in xrange(s):
    l.append(A(i, i + 1))

print l[0].a, l[0].b
input()

Итого 78 мегабайт. Оптимизировал почти на порядок. Причем не задумываясь.

baverman ★★★
()
Ответ на: комментарий от elverion

Пример был нужен чтобы показать огромный оверхед list'а, что я думаю мне удалось.

Тебе удалось показать, что ты недалекий КО. Ясен пень, что функционал листа по-сравнению с обычным массивом чего-то стоит.

baverman ★★★
()
Ответ на: комментарий от elverion

Они не устраивают любого, кто знает Питон.

Ну еще бы, ведь они выставляют питон не в лучшем свете.

То есть ты до сих пор не понял, что просто демонстрируешь свою профессиональную непригодность? Ну, я тебе не доктор.

исправь этот пример, чтобы он жрал не 400mb, а хотя бы 50

Python Optimization 101:


class A(object):
    __slots__ = ("a", "b")
    def __init__(self, a, b):
        self.a = a
        self.b = b

s = 1000000
l = [1] * s
for i in range(s):
    l.append(A(i, i + 1))


input()

23901 21.0 2.1 70104 65932 pts/19 S+ 12:25 0:01 python a.py

Не 50М, но и не 400М, как у тебя.

в C++ все это весило бы мегабайт 8

Код приведи, проверим твои знания Си++

tailgunner ★★★★★
()
Ответ на: комментарий от baverman

>Ясен пень, что функционал листа по-сравнению с обычным массивом чего-то стоит.

Ну да. Ради производительности приходится отказываться от полезных и удобных фич. Ничего не поделаешь, это питон.

elverion
()
Ответ на: комментарий от elverion

> Я тут правда тоже оптимизировал программу до 27 мегабайт (использовал g_slice_new из glib).

Кулпрогеры отаке.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Код приведи, проверим твои знания Си++

Тебе нужен код, чтобы убедится что массив из миллиона элементов каждый по 8 байт будет весить 8 мегабайт?

elverion
()
Ответ на: комментарий от elverion

> Тебе нужен код, чтобы убедится что массив из миллиона элементов каждый по 8 байт будет весить 8 мегабайт?

Байты я умею считать как минимум не хуже, чем ты, так что нет, не для этого. Ты сказал:

elverion> в C++ все это весило бы мегабайт 8

я хочу видеть «всё это» и, если оно и в самом деле эквивалентно приведенному коду на Питоне, хочу померять объем памяти.

tailgunner ★★★★★
()
Ответ на: комментарий от different_thing

> Что, в 3 range дропнули, а xrange переивеновали в range? А зря - списки это так круто, а итераторы - х.з. что.
нет, в третьем просто переименовали xrange в range. чтобы использовать список, а не кортеж, надо делать так

#было
a = range(10000)
#стало
a = list(range(10000))

пруф

memnek
()
Ответ на: комментарий от tailgunner

__slots__ = («a», «b»)

Черт, почему-то сразу не поверил в силу слотов.

baverman ★★★
()
Ответ на: комментарий от elverion

Какая прелесть, std::vector уже является аналогом Python list, а занесение объекта в vector по значению - аналогом занесения в list по ссылке. В общем, я присоединяюсь к мнению baverman.

Хочется посоветовать тебе какую-нибудь книгу вроде «Питон для анацефалов за 21 секунду». К сожалению, я такой не знаю.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>> его аналогом на Си будет вот это:

for (i = 0; i < 100000000; i++)

malloc(sizeof(int));


Хочется посоветовать тебе какую-нибудь книгу вроде «Питон для анацефалов за 21 секунду». К сожалению, я такой не знаю.


действительно к сожалению

aho
()
Ответ на: комментарий от tailgunner

> Ты пришел объяснить, что там с realloc, или тебе тоже нужен учебник по Питону?

нужен, но учитывая, какие у тебя примеры «аналога на Си», я лучше спрошу у кого-нибудь другого

aho
()
Ответ на: комментарий от aho

> учитывая, какие у тебя примеры «аналога на Си», я лучше спрошу у кого-нибудь другого

Спроси у него и о хорошем учебнике по Си/Си++

tailgunner ★★★★★
()
Ответ на: комментарий от aho

>> Спроси у него и о хорошем учебнике по Си/Си++

хорошо, но если не найду - ищи сам, уж извини

Я нашел давно, но ты же не станешь слушать моих советов.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я нашел давно

если там учат писать такой код:

for (i = 0; i < 100000000; i++)
malloc(sizeof(int));

то это был явно плохой учебник

aho
()
Ответ на: комментарий от aho

> если там учат писать такой код:

Такой код является ближайщим аналогом Python-кода, который написал elverion (я сделал скидку по потребляемой памяти и не стал хранить указатели). Иди уже, поговори с людьми, которым доверяешь, насчет учебника по Питону.

tailgunner ★★★★★
()
Ответ на: комментарий от elverion

проблема в том, что объект int занимает много, а не ссылки. int в ctypes занимает столько же, сколько в Си

michwill ★★★★★
()
Ответ на: комментарий от tailgunner

Список на 100000000 элементов есть? Да.

массив из 100млн элементов размером 4 байта уместился в 300кб? а быстрее процессора питон работать не умеет случаем? или хотя бы бесконечный цикл выполнить?

ckotinko ☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.