Комментарии 25
А можно вопрос, зачем здесь ООП? Вы показали, что встроенный namedtuple работает лучше самодельного класса. А зачем тут вообще нужны классы?
Класс в общем то не нужен. Нужна возможность обратиться к колонке по имени.
value = getattr(rowObject, «ColumnName»)
логичным видится замапить результат query на class
В реальной задаче правила проверки лежали в базе в виде (упрощённо)
таблица | имя колонки | операция | значение
value = getattr(rowObject, «ColumnName»)
логичным видится замапить результат query на class
В реальной задаче правила проверки лежали в базе в виде (упрощённо)
таблица | имя колонки | операция | значение
Нет, я конечно понимаю, что с классами удобнее и нагляднее, но если уж говорить про оптимизацию, то лучше наверное здесь просто использовать словарь. И читаемо будет, и быстро. Хотя надо проверить)
А зачем тут вообще нужен питон если проверки простейшие и напрашивается реализация непосредственно средствами sql?
Python программисту оптимизация должна показаться слишком очевидной.
Со __slots__ не пробовали замерить?
Named tuple реализован с помощью них, смысла в замерах нет.
Судя по выводу исходника сгенеренного класса, не совсем — кода там нагенерировано существенно больше чем просто
class Test(object):
__slots__ = ['field1','field2']
и работа с полями ведется через property, что тоже может повлиять на время создания инстансов
class Test(object):
__slots__ = ['field1','field2']
и работа с полями ведется через property, что тоже может повлиять на время создания инстансов
Вобщем, потестил слегка — размер созданных классов получается одинаковый, размер объектов слегка разный.
pastebin.com/dfdaxfMe
pastebin.com/dfdaxfMe
На создание инстансов класса тратится > 10сек
setattr(self, "Col{0}".format(x), values[x + 1])
То есть всё, что предлагается — хранить имена столбцов в описании класса (как делает namedtuple), а не в экземпляре. Ну ок, и что здесь неочевидного?
Кстати, внезапно всё на том же хабре по тэгу namedtuple: Именованные кортежи из выборок.
Почему у вас времена Sample 1/2 в 1-м «подходе» и 2-м существенно отличаются?
А кстати, интересно, насколько в этом случае будут производительны ORM-ки. Полагаю что результат будет на уровне Sample 2 и даже выше, поскольку этот тот же маппинг результатов на атрибуты объекта, но всё же интересно узнать насколько хуже.
на эту тему есть уже например тут
ради интереса сделал тест используя django
результаты:
Sample 1(tuple): 5.4720143202
Sample 2(RowWrapper): 19.0111270981
Sample 3(TupleClass): 5.80622400633
Sample 4(dict): 8.65782098053
Sample 5(django.model + raw()): 13.5116426081
обновлённый пример целиком тут
ради интереса сделал тест используя django
from django.db import models
def buildDjangoObject():
class DjangoObject(models.Model):
class Meta:
app_label = ''
DjangoObject.Id = models.IntegerField()
for x in xrange(ColsCount):
setattr(DjangoObject, "Col{0}".format(x), models.TextField())
return DjangoObject
DjangoObject = buildDjangoObject()
и def test5(self):
return tuple(row for row in DjangoObject.objects.raw(self.query))
результаты:
Sample 1(tuple): 5.4720143202
Sample 2(RowWrapper): 19.0111270981
Sample 3(TupleClass): 5.80622400633
Sample 4(dict): 8.65782098053
Sample 5(django.model + raw()): 13.5116426081
обновлённый пример целиком тут
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Неочевидная оптимизация по скорости при решении конкретной задачи на Python