Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 18, 2008 11:20:56

PyCraft
От:
Зарегистрирован: 2008-05-23
Сообщения: 81
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Не нашел в документации как делать сылки на объекты, чтобы сами объекты при этом не копировались в новую переменную.

Имеется такая конструкция
spisok = ''
затем в коде много раз
spisok += ‘какойтохвост’ #Здесь будет тормозить поиск и переаллоцирование памяти для новой строки
re.search('чтототам',self.spisok)
и т.д. и т.п.

Очевидно, что Питон каждый раз выполняет поиск в ассоциативном массиве.
Это медленно, особенно когда массив очень большой.
Как создать ссылку на текущий элемент?
И как наращивать строки без переприсваивания переменных. Ведь строки не мутабельны.
Может быть их можно преобразовать в мутабельную форму?

Что-то типа такого, код гипотетисский

buff = buffer(spisok) #Сссылка на строку или последовательность байтов
buff.append('какойтохвост') #Добавление последовательности байт в конец строки без переприсваивания переменной

print self.spisok # здесь результат всех операций со ссылкой



Отредактировано (Июнь 18, 2008 12:54:58)

Офлайн

#2 Июнь 18, 2008 13:12:10

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

PyCraft
Как создать ссылку на текущий элемент?
elem = my_dict[ "key" ]

Для строк можно попробовать StringIO



Отредактировано (Июнь 18, 2008 13:13:36)

Офлайн

#3 Июнь 18, 2008 13:29:10

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Хм.. запись видаelem = my_dict не является ссылкой. В данном случае объект будет копироваться по значению, за исключением случая, когда уже сам объект - mutable.
>>> d = {'key': 1}
>>> elem = d
>>> elem += 1
>>> elem
2
>>> d
1



Офлайн

#4 Июнь 18, 2008 14:17:13

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Это-то да, просто я имел ввиду применительно к StringIO уже.



Офлайн

#5 Июнь 18, 2008 14:18:18

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Правда не очень уверен, что он у себя внутри оптимально с памятью работает. Но в принципе можно ему фейковый буфер изначально большой подсунуть.



Офлайн

#6 Июнь 18, 2008 17:01:07

PyCraft
От:
Зарегистрирован: 2008-05-23
Сообщения: 81
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

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

Daevaorn
Правда не очень уверен, что он у себя внутри оптимально с памятью работает. Но в принципе можно ему фейковый буфер изначально большой подсунуть.
Вот методы класса StringIO
def __init__(self, buf = ''):
# Force self.buf to be a string or unicode
if not isinstance(buf, basestring):
buf = str(buf)
self.buf = buf
self.len = len(buf)
self.buflist = []
self.pos = 0
self.closed = False
self.softspace = 0

def write(self, s):
"""Write a string to the file.

There is no return value.
"""
_complain_ifclosed(self.closed)
if not s: return
# Force s to be a string or unicode
if not isinstance(s, basestring):
s = str(s)
spos = self.pos
slen = self.len
if spos == slen:
self.buflist.append(s)
self.len = self.pos = spos + len(s)
return
if spos > slen:
self.buflist.append('\0'*(spos - slen))
slen = spos
newpos = spos + len(s)
if spos < slen:
if self.buflist:
self.buf += ''.join(self.buflist)
self.buflist = [self.buf[:spos], s, self.buf[newpos:]]
self.buf = ''
if newpos > slen:
slen = newpos
else:
self.buflist.append(s)
slen = newpos
self.len = slen
self.pos = newpos
Получается что вместо реаллоцирования строки он создает новый элемент списка субстрок
Поскольку требуется только добавление в конец буфера, то проще будет самому список субстрок реализовать
Я надеялся, что есть эффективный способ работать со строкой как с массивом байт



Отредактировано (Июнь 18, 2008 17:09:32)

Офлайн

#7 Июнь 18, 2008 17:23:40

PyCraft
От:
Зарегистрирован: 2008-05-23
Сообщения: 81
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Тогда еще вопросец
Что будет быстрее вычисляться(и насколько быстрее) и/или требовать меньше памяти (и насколько меньше),
нулевой элемент кортежа или атрибут экземпляра класса?

d = {}
d[`key1`]=['чтототам1'] #исправлено - список вместо кортежа, т.к. кортежи не переприсваиваются
d[`key2`]=['чтототам2']
d[`key3`]=['чтототам3']
o = d[`key3`]
и дальше все операции с
o[0]

или через свойства класса

class ChtotoTam:
__init__(self,attribute='')
self.attribute=attribute

d = {}
d[`key1`]=ChtotoTam('чтототам1')
d[`key2`]=ChtotoTam('чтототам2')
d[`key3`]=ChtotoTam('чтототам3')
o = d[`key3`]

и дальше все операции с
o.attribute



Отредактировано (Июнь 18, 2008 18:18:54)

Офлайн

#8 Июнь 18, 2008 17:27:16

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Ну в качестве ещё одной цели для профайлинга и выявления самого лучшего варианта, я бы сделал так:

from cStringIO import StringIO
buf_size = 1024
buf = StringIO( "\0" * buf_size )
buf.seek(0)



Офлайн

#9 Июнь 18, 2008 17:36:11

PyCraft
От:
Зарегистрирован: 2008-05-23
Сообщения: 81
Репутация: +  0  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

Daevaorn
Ну в качестве ещё одной цели для профайлинга и выявления самого лучшего варианта, я бы сделал так:
from cStringIO import StringIO
buf_size = 1024
buf = StringIO( "\0" * buf_size )
buf.seek(0)
Если список субстрок не пуст, это это вызовет переаллоцирование памяти (см. += и join)
def seek(self, pos, mode = 0):
"""Set the file's current position.

The mode argument is optional and defaults to 0 (absolute file
positioning); other values are 1 (seek relative to the current
position) and 2 (seek relative to the file's end).

There is no return value.
"""
_complain_ifclosed(self.closed)
if self.buflist:
self.buf += ''.join(self.buflist)
self.buflist = []
if mode == 1:
pos += self.pos
elif mode == 2:
pos += self.len
self.pos = max(0, pos)



Офлайн

#10 Июнь 18, 2008 18:48:16

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Ссылка/псевдоним объекта?

PyCraft
Если список субстрок не пуст, это это вызовет переаллоцирование памяти (см. += и join)
Так он пуст как раз.
Только это не спасет:(



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version