Чтение онлайн

на главную - закладки

Жанры

Язык программирования Python
Шрифт:

Листинг

from timeit import Timer

t = Timer("""

res = ""

for k in range(1000000,1010000):

res += str(k)

«"")

print t.timeit(200)

t = Timer("""

res = []

for k in range(1000000,1010000):

res.append(str(k))

res = ",".join(res)

«"")

print t.timeit(200)

t = Timer("""

res = ",".join([str(k) for k in range(1000000,1010000)])

«"")

print t.timeit(200)

Разные версии Python дадут различные результаты прогонов:

Листинг

# Python 2.3

77.6665899754

10.1372740269

9.07727599144

# Python 2.4

9.26631307602

9.8416929245

7.36629199982

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

Если требуются более точные результаты, рекомендуется использовать метод repeat(n, k) - он позволяет вызывать timeit(k) n раз, возвращая список из n значений. Необходимо отметить, что на результаты может влиять загруженность компьютера, на котором проводятся испытания.

Оптимизация

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

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

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

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

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

В некоторых случаях работу программы на Python можно ускорить в несколько раз с помощью специального оптимизатора (он не входит в стандартную поставку Python, но свободно распространяется): psyco. Для ускорения программы достаточно добавить следующие строки в начале главного модуля программы:

Листинг

import psyco

psyco.full

Правда, некоторые функции не поддаются «компиляции» с помощью psyco. В этих случаях будут выданы предупреждения. Посмотрите документацию по psyco с тем, чтобы узнать ограничения в его использовании и способы их преодоления.

Еще одним вариантом ускорения работы приложения является переписывание критических участков алгоритма на языках более низкого уровня (С/С++) и использование модулей расширения из Python. Однако эта крайняя мера обычно не требуется или модули для задач, требующих большей эффективности, уже написаны. Например, для работы с растровыми изображениями имеется прекрасная библиотека модулей PIL (Python Imaging Library). Численные расчеты можно выполнять с помощью пакета Numeric и т.д.

Pychecker

Одним из наиболее интересных инструментов для анализа исходного кода Python программы является Pychecker. Как и lint для языка C, Pychecker позволяет выявлять слабости в исходном коде на языке Python. Можно рассмотреть следующий пример с использованием Pychecker:

Листинг

import re, string

import re

a = «a b c»

def test(x, y):

from string import split

a = «x y z»

print split(a) + x

test(['d'], 'e')

Pychecker выдаст следующие предупреждения:

Листинг

badcode.py:1: Imported module (string) not used

badcode.py:2: Imported module (re) not used

badcode.py:2: Module (re) re–imported

badcode.py:5: Parameter (y) not used

badcode.py:6: Using import and from … import for (string)

badcode.py:7: Local variable (a) shadows global defined on line 3

badcode.py:8: Local variable (a) shadows global defined on line 3

В первой строке импортирован модуль, который далее не применяется, то же самое с модулем re. Кроме того, модуль re импортирован повторно. Другие проблемы с кодом: параметр y не использован; модуль string применен как в операторе import, так и во from–import; локальная переменная a затеняет глобальную, которая определена в третьей строке.

Можно переписать этот пример так, чтобы Pychecker выдавал меньше предупреждений:

Листинг

import string

a = «a b c»

def test(x, y):

a1 = «x y z»

print string.split(a1) + x

test(['d'], 'e')

Теперь имеется лишь одно предупреждение:

Листинг

goodcode.py:4: Parameter (y) not used

Такое тоже бывает. Программист должен лишь убедиться, что он не сделал ошибки.

Исследование объекта

Даже самые примитивные объекты в языке программирования Python имеют возможности, общие для всех объектов: можно получить их уникальный идентификатор (с помощью функции id), представление в виде строки — даже в двух вариантах (функции str и repr); можно узнать атрибуты объекта с помощью встроенной функции dir и во многих случаях пользоваться атрибутом __dict__ для доступа к словарю имен объекта. Также можно узнать, сколько других объектов ссылается на данный с помощью функции sys.getrefcount. Есть еще сборка мусора, которая применяется для освобождения памяти от объектов, которые более не используются, но имеют ссылки друг на друга (циклические ссылки). Сборкой мусора (garbage collection) можно управлять из модуля gc.

Поделиться:
Популярные книги

Законы Рода. Том 12

Андрей Мельник
12. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 12

Второгодка. Книга 2. Око за око

Ромов Дмитрий
2. Второгодка
Фантастика:
героическая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Второгодка. Книга 2. Око за око

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Тринадцатый V

NikL
5. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый V

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Император Пограничья 1

Астахов Евгений Евгеньевич
1. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 1

Хозяин Стужи 4

Петров Максим Николаевич
4. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 4

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
Дважды одаренный. Том VI

Личный аптекарь императора. Том 6

Карелин Сергей Витальевич
6. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Личный аптекарь императора. Том 6

Шайтан Иван

Тен Эдуард
1. Шайтан Иван
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Шайтан Иван

Точка Бифуркации VIII

Смит Дейлор
8. ТБ
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации VIII

Черный Маг Императора 5

Герда Александр
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 5