Поскольку в Python 2 стандартный вызов open()
создает гораздо более простой файловый объект, чем вызов Python 3 open()
.Вызов Python 3 open
- это то же самое, что и io.open()
, и тот же фреймворк доступен на Python 2 .
Чтобы сделать это честное сравнение, вам нужно добавить следующую строку в начало вашего теста:
from io import open
С этим изменением время в Python 2 увеличится с 5,5 секунд до 37 секунд.По сравнению с этим показателем, 11 секунд, которые Python 3 берет на мою систему для запуска теста, действительно намного, намного быстрее .
Так что же здесь происходит?Библиотека io
предлагает гораздо больше функциональных возможностей, чем старый объект Python 2 file
:
- Файловые объекты, возвращаемые
open()
, состоят из 3-х уровней составной функциональности, что позволяет вам контролировать буферизациюи обработка текста. - Поддержка неблокирующих потоков ввода-вывода
- Согласованный интерфейс для широкого диапазона потоков
- Гораздо больший контроль над универсальная новая строка функция перевода .
- полная поддержка Unicode.
Эта дополнительная функциональность достигается за счет производительности.
Но ваш тест Python 2 читает строки байтов , переводы строки всегда переводятся в \n
, а файловый объект, с которым работает код, довольно близок к предоставленному OS файловому примитиву,с все минусы .В Python 3 обычно требуется обрабатывать данные из файлов в виде текста, поэтому при открытии файла в текстовом режиме вы получаете файловый объект, который декодирует двоичные данные в объекты Unicode str
.
Итак, как вы можете сделатьдела идут быстрее на Python 3?Это зависит от вашего конкретного варианта использования, но у вас есть несколько вариантов:
- Для файлов в текстовом режиме отключите универсальную обработку новой строки, особенно при обработке файла, в котором используются окончания строк, которые отличаются от стандарта платформы.Установите для параметра
newline
ожидаемую последовательность символов новой строки, например \n
.Двоичный режим поддерживает только \n
в качестве разделителя строк. - Обрабатывает файл как двоичные данные и не декодирует до
str
.В качестве альтернативы, декодирование в Latin-1, прямое сопоставление один на один из байта в кодовую точку.Это вариант, когда ваши данные также только для ASCII, где Latin-1 пропускает проверку ошибок байтов в диапазоне 0-127, а не 0-255.
При использовании mode='rb'
, Python 3 может легко соответствовать временам Python 2, тест занимает в моей системе всего 5,05 секунды, используя Python 3.7.
Использование latin-1
в качестве кодека по сравнению с UTF-8 (обычное значение по умолчанию)только небольшая разница;UTF-8 может быть очень эффективно декодирован.Но это может иметь значение для других кодеков.Обычно вы хотите явно установить параметр encoding
и не полагаться на используемую по умолчанию кодировку .