Почему существует разница между созданием класса в python 2.7 и производительности python 3.4

from timeit import Timer as T def calc(n): return T("class CLS(object): pass").timeit(n) print(calc(90000)) print(calc(90000)) print(calc(90000)) # python3.4 1.1714721370008192 1.0723806529986177 1.111804607000522 # python2.7 15.7533519268 16.7191421986 16.8397979736 

Почему существует такая разница в времени создания класса с использованием разных версий python? Протестировано на той же машине:

  • i5-3450 CPU @ 3,10 ГГц
  • 8 гб баранов

2 Solutions collect form web for “Почему существует разница между созданием класса в python 2.7 и производительности python 3.4”

timeit отключает сборщик мусора, который в противном случае нарушает циклы, которые сохраняют объект класса живым. Таким образом, ни один из классов не освобождается, пока не закончится.

object.__subclasses__() ссылается на эти классы через внутренний набор слабых ссылок. Старая реализация tp_subclasses на основе списка tp_subclasses поиск по всему списку каждый раз, чтобы найти мертвую ссылку, которую можно заменить. Этот процесс занимает больше времени с каждым дополнительным подклассом. С другой стороны, новый дизайн на основе dict в 3.4 может добавить ссылку в постоянное время. См. Вопрос 17936 .


Спасибо @MichaelYounkin за то, что он указывает, что это также медленно в 3.2. Первоначально я попытался сократить разницу в производительности до изменения в распределении малогабаритных объектов между 2.x и 3.x, но после прочтения его комментария я обнаружил, что даже 3.3 был значительно медленнее 3.4. Поэтому я просмотрел файл-файл typeobject.c, чтобы просмотреть последние изменения.

Ну, проблема, похоже, связана с классами старого стиля и нового стиля в python 2.7.

В python 3.4 вы можете видеть, что разница между использованием объекта и его использованием – это просто загрузка символа (не такая значимая):

 C:\TEMP>C:\Python34\python.exe Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> def a(): ... class A(object): pass ... >>> def b(): ... class B(): pass ... >>> import dis >>> dis.dis(a) 2 0 LOAD_BUILD_CLASS 1 LOAD_CONST 1 (<code object A at 0x020B8F20, file "<stdin>", line 2>) 4 LOAD_CONST 2 ('A') 7 MAKE_FUNCTION 0 10 LOAD_CONST 2 ('A') 13 LOAD_GLOBAL 0 (object) # Extra step, not that expensive. 16 CALL_FUNCTION 3 (3 positional, 0 keyword pair) 19 STORE_FAST 0 (A) 22 LOAD_CONST 0 (None) 25 RETURN_VALUE >>> dis.dis(b) 2 0 LOAD_BUILD_CLASS 1 LOAD_CONST 1 (<code object B at 0x020B8D40, file "<stdin>", line 2>) 4 LOAD_CONST 2 ('B') 7 MAKE_FUNCTION 0 10 LOAD_CONST 2 ('B') 13 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 16 STORE_FAST 0 (B) 19 LOAD_CONST 0 (None) 22 RETURN_VALUE >>> 

Хотя на Python 2.7 у вас есть еще один шаг, который включает LOAD_TUPLE:

 C:\Users\jsargiot\Downloads\so>C:\Python27\python.exe Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> def a(): ... class A(object): pass ... >>> def b(): ... class B(): pass ... >>> import dis >>> dis.dis(a) 2 0 LOAD_CONST 1 ('A') 3 LOAD_GLOBAL 0 (object) # First extra step (just like 3.4) 6 BUILD_TUPLE 1 # Second extra step, expensive 9 LOAD_CONST 2 (<code object A at 01EAEA88, file "<stdin>", line 2>) 12 MAKE_FUNCTION 0 15 CALL_FUNCTION 0 18 BUILD_CLASS 19 STORE_FAST 0 (A) 22 LOAD_CONST 0 (None) 25 RETURN_VALUE >>> dis.dis(b) 2 0 LOAD_CONST 1 ('B') 3 LOAD_CONST 3 (()) 6 LOAD_CONST 2 (<code object B at 01EB8EC0, file "<stdin>", line 2>) 9 MAKE_FUNCTION 0 12 CALL_FUNCTION 0 15 BUILD_CLASS 16 STORE_FAST 0 (B) 19 LOAD_CONST 0 (None) 22 RETURN_VALUE >>> 
  • Применить порядок списка в другие списки
  • Кнопка Python / Tkinter и запись в том же окне
  • Что означает «таблица» в функции string.translate?
  • Как расширить список целых чисел на основе порога?
  • Проверьте, существует ли ключ в списке Python
  • Сценарий Python, чтобы делать что-то в одно и то же время каждый день
  • Согласовать каждый элемент списка с каждым элементом второго списка
  • Как я могу получить третью пятницу месяца на Python?
  • Эффективный способ подсчета True и False
  • поиск дубликатов в списке списков
  • Тайм-аут функции python в окнах
  •  
    Interesting Posts for Van-Lav

    как использовать «/» (разделитель каталогов) в Linux и Windows?

    метод класса __instancecheck__ не работает

    Скопированный пакет не может быть получен

    Сегментация и регистрация изображений с помощью SimpleITK

    «Необработанное исключение в потоке, запущенном« Ошибка в sys.excepthook »во время восстановления zodb pack

    Python, argparse: как иметь nargs = 2 с типом = str и type = int

    Самый простой способ запустить сценарий ожидания из python

    Python: чтение сертификата pkcs12 с pyOpenSSL.crypto

    Нарисуйте SVG-образ в GTK3 из источника SVG в python

    Почему Pariko зависает, если вы используете его при загрузке модуля?

    Какая разница между синтаксическим разбором HTML и обходом веб-страниц в python

    Последовательный способ перенаправления stdin и stdout на файлы в python с использованием optparse

    Как открыть окно вывода сценария Python?

    Azure python sdk для мониторинга ресурсов VM

    Назначение динамического значения переменной класса изнутри класса

    Python - лучший язык программирования в мире.