Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 11, 2008 11:45:33

ReinRaus
От:
Зарегистрирован: 2008-10-24
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

Мне нужно сделать класс, где со строками длиной 20-100 кб будет производится много операций по преобразованию их, поиску в них итп. Суть не в этом.
Производительность работы будет выше, если:
1. Эти строки будут объявлены вне класса, а в самом классе я буду обращатся к ним через global.
2. Если я их объявлю как атрибуты класса.
Подскажите.



Офлайн

#2 Ноя. 11, 2008 11:55:26

Viper
От:
Зарегистрирован: 2006-11-08
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

При работе со строками длиной 20-100 кб думаю скоростью обращения к переменным можно пренебреч, имхо. А вообще можно создать локальную переменную в начале метода и использовать её.



Офлайн

#3 Ноя. 11, 2008 12:09:19

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

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

Но разница будет, global - вариант будет быстрее немного. Но глобальные переменные - зло, от которого стоит избавляться.
Поэтому предлагаю такой вариант: строки объявить как атрибуты класса, но перед работой с ними - вносить их в локальный неймспейс функции:
stroka = self.stroka
это вариант будет еще быстрее =)



Офлайн

#4 Ноя. 11, 2008 12:54:18

ReinRaus
От:
Зарегистрирован: 2008-10-24
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

Мне самому хотелось бы как атрибуты класса, но меня смущает то, что я не знаю как организована работа с памятью в классах питона, а точнее я знаю, что к примеру вот такой код очень низок по производительности:

string100kb='сто килобайт текста'

def myfunc(text):
text.decode('utf-8')
return text

string100kb=myfunc(string100kb)
это я для примера привел, но это непроизводительно.

Меня в классах смущает всего одно- это объявление методов класса. def myfunc_in_myclass(self, other_param)
если в питоне экземпляр класса передается в метод класса как объект, то это будет очень и очень медленно. Если же передается указатель на экземпляр класса, то это будет иметь такую же почти скорость, как и использование global.

Хм… В общем вопрос теперь сводится к другому:
1. Питон передает в метод класса весь экземпляр класса, для которого вызван метод.
2. Питон передает указатель на экземпляр класса.

(указатель я имею ввиду по аналогии с делфи и си- не само значение объекта, а адрес памяти где он находится)



Офлайн

#5 Ноя. 11, 2008 13:01:04

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

он передаст по имени, что является аналогом указателя.



Офлайн

#6 Ноя. 11, 2008 13:06:28

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

не понял, почему ты считаешь, что приведенный код будет медленным? =)
вот:

string100kb='mama mila ramu'

def myfunc(text):
print id(text)
text.decode('utf-8')
return text

print id(string100kb)
string100kb=myfunc(string100kb)
print id(string100kb)

>>>10891376
>>>10891376
>>>10891376
везде печатается адрес в памяти одной и той-же строки. т.е. опять-же передается указатель.

временные затраты по сравнению с
string100kb.decode('utf-8')
будут только на вызов фукнции.



Отредактировано (Ноя. 11, 2008 13:13:52)

Офлайн

#7 Ноя. 11, 2008 13:09:49

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

lorien
Не совсем так.
Строка - неизменяемый объект ( вот личии от MutableString например или листа),
поэтому при операции a += u'попятчсо' ты создаешь новый строку путем сложения старой и u'попятчсо'.
При этому старая останеится в памяти (только имени у нее не будет), пока ее сборщик мусора не соберет.



Отредактировано (Ноя. 11, 2008 13:14:52)

Офлайн

#8 Ноя. 11, 2008 13:19:40

ReinRaus
От:
Зарегистрирован: 2008-10-24
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

я нуб ))) нафик я тему создавал…
все решилось банальным тестом:

# -*- coding: utf8 -*-
import time
a="абвгдежзиклмнопр"
b=""
for i in range(1,10000): b+=a

timestart=time.time()
class myclass():
def func1(self):
timestart=time.time()
global b
for i in range(1, 5000): c=b.decode("utf-8")
print time.time()-timestart
def func2(self):
timestart=time.time()
for i in range(1, 5000): c=self.aa.decode("utf-8")
print time.time()-timestart
def func3(self):
global b
self.aa=b


s=myclass()
s.func1()
s.func3()
s.func2()
результаты были такие:
>>> ================================ RESTART ================================
>>>
10.3120000362
10.2809998989
>>>
в общем как атрибуты класса даже быстрее, чем глобальные.



Офлайн

#9 Ноя. 11, 2008 13:30:16

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопросик про производительность работы.

ReinRaus
в общем как атрибуты класса даже быстрее, чем глобальные.
а теперь добавь в самом низу еще один вызов s.func1() и ты увидишь, что глобальные всетки быстрее децел =)

при первом вызове s.func1() - интрепретатор еще не прогрелся %)

Это я к тому, что меряешь ты неправильно.
Время поиска переменной - настолько мало по сравнению с обработкой строк, что на 5000 итераций, гораздо большее влиение оказывают случайные флуктуации выделения памяти под строки и сборка мусора.



Отредактировано (Ноя. 11, 2008 13:39:13)

Офлайн

#10 Ноя. 11, 2008 16:09:34

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

Вопросик про производительность работы.

shiza
+1



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version