python: займет ли класс с большим количеством методов больше времени для инициализации?

У меня есть программа, которая должна непрерывно создавать тысячи объектов из класса, который имеет около 12–14 методов. Приведет ли тот факт, что они имеют сложный класс, к быстродействию из-за создания более простого объекта, такого как список или словарь, или даже другого объекта с меньшим количеством методов?

Некоторые подробности о моей ситуации: у меня есть куча "текстовых" объектов, которые постоянно создают и обновляют "распечатки" их содержимого. У объектов печати есть много методов, но только несколько атрибутов. Объекты печати не могут содержаться в текстовых объектах, потому что текстовые объекты должны быть "многократно используемыми" и делать несколько независимых копий своих отпечатков, чтобы исключить просто замену атрибутов объектов печати при обновлении.

Мне лучше,

  • Постоянно создавать новые объекты печати со всеми их методами при обновлении приложения?
  • Распутывание класса и превращение объектов печати в простые структуры и методы в независимые функции, которые принимают объекты в качестве аргументов?

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

3 ответа

Решение

Неважно, насколько сложный класс; когда вы создаете экземпляр, вы сохраняете только ссылку на класс вместе с экземпляром. Все методы доступны через одну ссылку.

Нет, это не должно иметь значение.

Учтите, что когда вы делаете следующее:

a = Foo()
a.bar()

Призыв к bar Этот метод фактически переводится под обложками:

Foo.bar(a)

Т.е. bar является "статическим" в определении класса, и существует только один экземпляр функции. Когда вы смотрите на это так, это говорит о том, что нет, не будет существенного влияния числа методов. Методы создаются при первом запуске программы Python, а не при создании объектов.

Я сделал некоторое тестирование.

У меня есть следующая функция:

def call_1000000_times(f):
     start = time.time()
     for i in xrange(1000000):
             f(a=i, b=10000-i)
     return time.time() - start

Как вы можете видеть, эта функция берет другую функцию, вызывает ее 1000000 раз и возвращает время ожидания в секундах.

Я также создал два класса:

Небольшой класс:

class X(object):
     def __init__(self, a, b):
             self.a = a
             self.b = b

И довольно большой:

class Y(object):
     def __init__(self, a, b):
         self.a = a
         self.b = b
     def foo(self): pass
     def bar(self): pass
     def baz(self): pass
     def anothermethod(self):
         pass
     @classmethod
     def hey_a_class_method(cls, argument):
         pass
     def thisclassdoeswaytoomuch(self): pass
     def thisclassisbecomingbloated(self): pass
     def almostattheendoftheclass(self): pass
     def imgonnahaveacouplemore(self): pass
     def somanymethodssssss(self): pass
     def should_i_add_more(self): pass
     def yes_just_a_couple(self): pass
     def just_for_lolz(self): pass
     def coming_up_with_good_method_names_is_hard(self): pass

Результаты, достижения:

>>> call_1000000_times(dict)
0.2680389881134033
>>> call_1000000_times(X)
0.6771988868713379
>>> call_1000000_times(Y)
0.6260080337524414

Как видите, разница между большим классом и небольшим классом очень мала, и в этом случае большой класс даже быстрее. Я предполагаю, что если бы вы запускали эту функцию несколько раз с одним и тем же типом и усредняли числа, они были бы еще ближе, но сейчас уже 3 часа ночи, и мне нужно поспать, поэтому я не собираюсь устанавливать это прямо сейчас.

С другой стороны, просто звоню dict был примерно в 2,5 раза быстрее, поэтому, если ваше узкое место - инстанцирование, это может быть местом для оптимизации вещей.

Однако будьте осторожны с преждевременной оптимизацией. Классы, объединяя данные и код, могут сделать ваш код более легким для понимания и построения (любители функционального программирования, это не место для спора). Было бы неплохо использовать профилировщик Python или другие инструменты измерения производительности, чтобы узнать, какие части вашего кода замедляют его.

Другие вопросы по тегам