Как стать автором
Обновить

Комментарии 25

А можно вопрос, зачем здесь ООП? Вы показали, что встроенный namedtuple работает лучше самодельного класса. А зачем тут вообще нужны классы?
Класс в общем то не нужен. Нужна возможность обратиться к колонке по имени.
value = getattr(rowObject, «ColumnName»)
логичным видится замапить результат query на class

В реальной задаче правила проверки лежали в базе в виде (упрощённо)
таблица | имя колонки | операция | значение
Нет, я конечно понимаю, что с классами удобнее и нагляднее, но если уж говорить про оптимизацию, то лучше наверное здесь просто использовать словарь. И читаемо будет, и быстро. Хотя надо проверить)
быстрее как раз не получилось
def test4(self):
    return tuple(dict(zip(Columns, row)) for row in self.cursor.execute(self.query))

Результат:
Sample 1: 4.27413250617
Sample 2: 15.0353127761
Sample 3: 4.66455941441
Sample 4: 6.84044835724
А вроде по цифрам — так получилось. :)
Внимательнее! 4) быстрее чем 2) но медленнее чем 3)
А зачем тут вообще нужен питон если проверки простейшие и напрашивается реализация непосредственно средствами sql?
Это было требование к задаче. Само собой решение на stored procedure предлагалось… Пришлось крутиться.
Python программисту оптимизация должна показаться слишком очевидной.
Фраза в заголовке " для не Python программиста" показалась лишней информацией. Кто разбирается в теме просмотрит и быстро пролистнёт дальше.
Следуя этой логике все статьи стоит начинать со слова «неочевидный», ты ничего не теряешь, просто будет больше тех, кто зайдет и пролистнет дальше.
Со __slots__ не пробовали замерить?

Named tuple реализован с помощью них, смысла в замерах нет.
Судя по выводу исходника сгенеренного класса, не совсем — кода там нагенерировано существенно больше чем просто

class Test(object):
    __slots__ = ['field1','field2']

и работа с полями ведется через property, что тоже может повлиять на время создания инстансов
Вобщем, потестил слегка — размер созданных классов получается одинаковый, размер объектов слегка разный.
pastebin.com/dfdaxfMe
Интересно, почему размер объектов разный, и тем более интересно почему у класса меньше

Хотя, следуя логике — в named tuple кроме этих двух полей есть ещё и что-то, относящееся к самому named tuple, так что всё ОК.
На создание инстансов класса тратится > 10сек

setattr(self, "Col{0}".format(x), values[x + 1])

То есть всё, что предлагается — хранить имена столбцов в описании класса (как делает namedtuple), а не в экземпляре. Ну ок, и что здесь неочевидного?
Для НЕ python программиста очень даже неочевидно. Наверное зря я не указал это в тексте.
А по запросу python namedtuple не выдаёт эту статью.
Почему у вас времена Sample 1/2 в 1-м «подходе» и 2-м существенно отличаются?
писал в два подхода, возможно в фоне что то работало(тот же антивирус например)
А кстати, интересно, насколько в этом случае будут производительны ORM-ки. Полагаю что результат будет на уровне Sample 2 и даже выше, поскольку этот тот же маппинг результатов на атрибуты объекта, но всё же интересно узнать насколько хуже.
на эту тему есть уже например тут
ради интереса сделал тест используя 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

обновлённый пример целиком тут
Спасибо.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории