Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 18, 2008 18:49:23

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

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

Тест показал, что классы работают быстрее списков.
Тест выполнялся несколько раз, позиции блоков кода каждый раз менялись местами!
Как оказалось последовательность выполнения влияет на результат
Сравнивались лучшие результаты для первого по исполнению блока кода и худшие для второго
Лушее время:
class=11.28 spisok=12.78
Худшее время:
class=19.39 spisok=22.71

import time

class SockBuff:
def __init__(self,buff=''):
self.buff=buff

if __name__=="__main__":
m = 100
s = 'lbahbvlahsvbasbvbvhvblsvb'

List2 = {}
t = time.time()
for i in range(0,m):
List2[`i`]=[s]
for j in range(0,i):
o = List2[`j`]
for k in range(0,m):
o[0] += s
dt = time.time()-t
print "spisok=",dt

del List2
time.sleep(20)

List1 = {}
t = time.time()
for i in range(0,m):
List1[`i`]=SockBuff(s)
for j in range(0,i):
o = List1[`j`]
for k in range(0,m):
o.buff += s
dt = time.time()-t
print "class=",dt



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

Офлайн

#2 Июнь 18, 2008 19:06:45

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

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

Daevaorn
Только это не спасет:
Для цели закачки из сокета в буфер, с проверкой начала и конца сообщения по протоколу, после каждого селекта/ресива, ни StringIO, ни свой список, ни классы не спасут. Всё равно на каждом цикле нужно проверять суммарный массив, а для этого его нужно объединить. Искомый контекст может находиться по частям в двух субстроках. Таким образом, никакой выгоды не будет.
Нужен именно способ работы через указатели - как в C или по крайней мере возможность изменять содержимое заранее выделенного байтового массива

….

Однако сStringIO (реализация на C) нас спасёт. По тесту работает ~ в 4 раза быстрее StringIO и ~ в 40 раз быстрее строк.
Хотя конечно и там не самый эффективный алгоритм. Он же не знает как лучше и сколько аллоцировать при каждом вызове write(s).

Самый эффективный нужно самому на С писать и добавлять в качестве модуля.



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

Офлайн

#3 Июнь 18, 2008 22:11:57

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

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

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



Офлайн

#4 Июнь 18, 2008 22:13:49

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

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

для байтовых массивов существует модуль array. однако мысль о том, что нужный специфический тип данных нужно писать на Си, – правильная.



Офлайн

#5 Июнь 19, 2008 14:42:20

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

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

Daevaorn
buf = StringIO( “\0” * buf_size ) buf.seek(0)
Заливка нулями при создании или в процессе перезаписи тормозит процесс. Проверено в разных вариантах.

Выводы не утешительные…

Вот результаты нового теста
1) class o.buff = 0.0469999313354
2) spisok = 0.047000169754
3) StringIO питон = 0.219000101089
4)cStringIO без заливки = 0.108999967575
5)cStringIO с заливкой = 0.140000104904

Вот сам тест (имитация конечно)
import time, StringIO, cStringIO

class SockBuff:
def __init__(self,buff=''):
self.buff=buff

if __name__=="__main__":
n = 2 #Среднее количество подкачек пакетов
m = 5000 #Количество сокетов
s = 'x' * 1020 #пакет данных
o = 'Объект'
son = 10 #проспаться 10 секунд для очистки памяти
buf_size = 1024 #размер пакета
max_buf_size = buf_size * n #размер буфера для сборки пакетов

List5 = {}
t = time.time()
#создание объектов
for i in range(0,m):
o=cStringIO.StringIO()
o.write("\0" * max_buf_size)
o.seek(0)
List5[`i`]=o
#чтение данных
for j in range(0,n):
for k in range(0,m):
o = List5[`k`]
o.write(s)
v=o.getvalue()
if len(v)>=buf_size:
x=v[:buf_size]
o.seek(0)
o.write(v[buf_size:])
dt = time.time()-t
print "5)cStringIO=",dt
del List5
time.sleep(son)

List4 = {}
t = time.time()
for i in range(0,m):
List4[`i`]=cStringIO.StringIO()
for j in range(0,n):
for k in range(0,m):
o = List4[`k`]
o.write(s)
v=o.getvalue()
if len(v)>=buf_size:
x=v[:buf_size]
o.seek(0)
o.write(v[buf_size:])
dt = time.time()-t
print "4)cStringIO=",dt
del List4
time.sleep(son)

List3 = {}
t = time.time()
for i in range(0,m):
List3[`i`]=StringIO.StringIO()
for j in range(0,n):
for k in range(0,m):
o = List3[`k`]
o.write(s)
v=o.getvalue()
if len(v)>=buf_size:
x=v[:buf_size]
o.seek(0)
o.write(v[buf_size:])
dt = time.time()-t
print "3) StringIO=",dt
del List3
time.sleep(son)

List2 = {}
t = time.time()
for i in range(0,m):
List2[`i`]=['']
for j in range(0,n):
for k in range(0,m):
o = List2[`k`]
o[0]+=s
if len(o[0])>=buf_size:
x=o[0][:buf_size]
o[0]=o[0][buf_size:]
dt = time.time()-t
print "2) spisok =",dt
del List2
time.sleep(son)

List1 = {}
t = time.time()
for i in range(0,m):
List1[`i`]=SockBuff()
for j in range(0,n):
for k in range(0,m):
o = List1[`k`]
o.buff+=s
if len(o.buff)>=buf_size:
x=o.buff[:buf_size]
o.buff=o.buff[buf_size:]
dt = time.time()-t
print "1) class =",dt
del List1
time.sleep(son)



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

Офлайн

#6 Июнь 19, 2008 15:07:46

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

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

bialix
В Питоне все имена являются ссылками на объекты и никакого копирования кроме явного никогда не производится.
оператор присваивания = работает по разному для разных типов объектов
Немутабельные (строки, числа) объекты всегда копируются - “семантика компирования”
Мутабельные объекты (списки, словари, классы) присваиваются по ссылке - “семантика указателей”
Для кортежей работает “семантика указателей” но они немутабельны, т.е. их нельзя изменить.

Меня интересуют строки и байтовые массивы, а также способы ускорения работы с ними.



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

Офлайн

#7 Июнь 19, 2008 15:26:24

hellt
От:
Зарегистрирован: 2008-03-14
Сообщения: 45
Репутация: +  0  -
Профиль   Отправить e-mail  

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

PyCraft
bialix
В Питоне все имена являются ссылками на объекты и никакого копирования кроме явного никогда не производится.
оператор присваивания = работает по разному для разных типов объектов
Немутабельные (строки, числа) объекты всегда копируются - “семантика компирования”
Мутабельные объекты (списки, словари, классы) присваиваются по ссылке - “семантика указателей”
Для кортежей работает “семантика указателей” но они немутабельны, т.е. их нельзя изменить.

Меня интересуют строки и байтовые массивы, а также способы ускорения работы с ними.
its called shared reference
a = 23 # not mutable в памяти создается объект 23 и а указывает на этот объект в памяти

b = a # теперь b ссылается на область памяти в которой лежит число 23

a = 0 # создается новый объект в памяти и а теперь ссылается на него. b по прежнему ссылается на объект 23



IDLE 1.2.2
>>> a = 23
>>> b = a
>>> print “0x%X” % id(a)
0xA65650
>>> print “0x%X” % id(b)
0xA65650
>>>



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

Офлайн

#8 Июнь 19, 2008 15:54:46

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

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

hellt
its called shared reference
a = 23 # not mutable в памяти создается объект 23 и а указывает на этот объект в памяти

b = a # теперь b ссылается на область памяти в которой лежит число 23

a = 0 # создается новый объект в памяти и а теперь ссылается на него. b по прежнему ссылается на объект 23

Код: :python:

IDLE 1.2.2
>>> a = 23
>>> b = a
>>> print “0x%X” % id(a)
0xA65650
>>> print “0x%X” % id(b)
0xA65650
>>>
Это, ровным счетом, ни о чем не говорит, точнее бесполезно. Мы же не можем с этой областью памяти напрямую работать.
А питон работает по своей логике.

a=1
b=a
b += 1
print a
1
print b
2

a=1
b=a
a += 1
print b
1
print a
2

и никакой пользы от ссылки b в обоих случаях мы не получаем.



Отредактировано (Июнь 19, 2008 16:08:05)

Офлайн

#9 Июнь 19, 2008 16:18:48

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

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

bialix
для байтовых массивов существует модуль array.
А как с ним работать? там нет функции вставки без сдвига вправо, длина массива какая-то ненадежная.
Пример можешь показать?

1) создать массив элементов типа Т, начальный размер массива N, заполнен 0
2) довавить в массив строку (желательно при этом не переаллоцировать память)
3) определить длину массива (но не буфера в памяти, т.к. боюсь он может отличаться от реальной длины)
4) скопировать первые M элементов в переменную
5) часть массива начиная с позиции M до конца сдвинуть в начало (желательно опять же не переаллоцировать память)

в общем, аналогично приведенному тесту.



Отредактировано (Июнь 19, 2008 16:24:39)

Офлайн

#10 Июнь 19, 2008 16:38:13

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

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

PyCraft
1) class o.buff = 0.0469999313354
2) spisok = 0.047000169754
3) StringIO питон = 0.219000101089
4)cStringIO без заливки = 0.108999967575
5)cStringIO с заливкой = 0.140000104904
Ага медлено. Но видимо StringIO не для этой задачи
PyCraft
Это, ровным счетом, ни о чем не говорит, точнее бесполезно.
Это говорит о том что в питоне везде ссылки(через COW), и ваш прошлый тезис неправилен.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version