BufferedReader в Python 2.x против Python 3.x - PullRequest
2 голосов
/ 25 декабря 2010

У меня есть программа, которая работает на Python 2 и Python 3, но есть резкое различие в скорости.Я понимаю, что в коммутатор был внесен ряд внутренних изменений, но разница в io.BufferedReader действительно велика.В обеих версиях я использую io.BufferedReader, потому что основной цикл программы требует данных только по одному байту за раз.Вот выдержка из вывода cProfile для скрипта (см. cumtime , а не totaltime):

Python 2:
 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 36984   0.188    0.000    0.545    0.000   io.py:929(read)

Python 3:
 36996    0.063   0.000    0.063    0.000   {method 'read' of '_io.BufferedReader' objects}

Когда я печатаю объект, оба возвращают что-то вроде io.BufferedReader, поэтому янаверняка они оба используют BufferedReader.

Здесь - рассматриваемый код.См. Строку 28. Вызывающий абонент отвечает за настройку bufstream.Я использовал bufstream = io.open('testfile', 'rb')

Почему такая большая разница в скорости BufferedReader для чтения отдельных файлов в файлах и как я могу «исправить» проблему с Python 2.x?Я использую Python 2.6 и Python 3.1.

Ответы [ 2 ]

6 голосов
/ 25 декабря 2010

Чтобы дать вам более полный ответ, вам нужно увидеть ваш код (или, точнее, исполняемый код вашего кода).

Однако частичный ответ можно найти в выводе вашего профиля: io.py предполагает, что "Python 2" (во избежание сомнений, укажите фактические номера версий) реализует BufferedReader в Python, тогда как _io.BufferedReader предполагает, что "Python3 "реализует это в C.

Последние новости: размер Python 2.6 io.py превышает 64 КБ и включает в себя следующий комментарий:

# This is a prototype; hopefully eventually some of this will be
# reimplemented in C.

Python 2.7 io.py имеет размер около 4 КБ и выглядит как тонкая оболочка модуля _io.

Если вам нужна реальная помощь с обходным решением для 2.6, покажите свой код.

Вероятный обходной путь для Python 2.6

Вместо:

test = io.open('test.bmp', 'rb')

сделать это:

test = open('test.bmp', 'rb')

Некоторые приблизительные временные цифры , включая недостающее звено (Python 2.7):

Windows 7 Pro, 32-битный файл, размер файла около 5 МБ, код:

while 1:
    c = f.read(1)
    if not c: break

2.6: io.open 20.4s, open 5.1s
2.7: io.open  3.3s, open 4.8s # io.open is better
3.1: io.open  3.6s, open 3.6s # effectively same code is used

Итак, лучшая история, по-видимому, такова: в общем, не обращайте внимания на io.open, если у вас нет веских причин, например, Вы хотите, чтобы 2.7 шел быстрее.

4 голосов
/ 25 декабря 2010

Использование 2.7 должно решить эту проблему. См. PEP 3116 и Python 2.7 doc .

Часть модуля io написана на python в 2.6, а в 2.7+ весь модуль написан на C

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...