Давайте проверим вышесказанное, смоделировав обе ситуации. У нас есть функция func, которая будет вызываться в первом случае по индексу из списка, во втором: через условие. Для реального замера времени вызовем функцию по 100000 раз. Итак,
import time
def func():
. . . . b = 55 * 22
t=time.clock()
p = 0
while p < 100000:
. . . . [func, lambda: None][0]()
. . . . p += 1
print 'example #1: %s sec.' %str(time.clock() - t)
t = time.clock()
p = 0
while p < 100000:
. . . . if p >= 0:
. . . . . . . . func()
. . . . p += 1
print 'example #2: %s sec.' %str(time.clock() - t)
#-------------------------
результат:
>>>
example #1: 9.3125 sec.
example #2: 6.3125 sec.
>>>
вот те раз... Если в первом случае вместо списка использовать кортеж, то время конечно будет немного меньше, но тенденция останется.
#-------------------------
Давайте увеличим количество условий, ну и соответственно увеличим количество пунктов в списке:
t=time.clock()
p = 0
while p < 100000:
. . . . [func, lambda: None, lambda: None, lambda: None, lambda: None, lambda: None][0]()
. . . . p += 1
print 'example #1: %s sec.' %str(time.clock() - t)
t = time.clock()
p = 0
while p < 100000:
. . . . if p == -1:
. . . . . . . . func()
. . . . elif p == -2:
. . . . . . . . func()
. . . . elif p == -3:
. . . . . . . . func()
. . . . elif p == -4:
. . . . . . . . func()
. . . . elif p >= 0:
. . . . . . . . func()
. . . . p += 1
print 'example #2: %s sec.' %str(time.clock() - t)
#-------------------------
результат:
>>>
example #1: 13.28125 sec.
example #2: 9.109375 sec.
>>>
в общем, 'думайте сами, решайте сами, ...'
- Главная
- Форум
- Программирование
- Программирование на Python
- Ноу хау - от мастеров на заметку » Страница 3
Ноу хау - от мастеров на заметку » Страница 3
-Программирование на Python
Примерчик-то не совсем корректный, dimy44, а ? Ты же понимаешь, что сто тыщ раз вызывать конструктор пусть даже неизменяемого типа, как кортеж, влечет накладные расходы.
Вот мой примерчик в аттаче, ну и прямо здесь запостить нужно, файлы-то долго не живут:
def foo(): pass
def func():
from time import clock # локальный импорт; дергать модуль из глобальной области видимости в цикле в функции для замера производительности плохая идея
funcs = [foo, lambda: None]
## если список функций "func" не локальный, то можно сделать локальную ссылку на него, тоже ускорит доступ к нему и к функциям:
## local_funcs = func
p = 0
t= clock()
while p < 100000:
funcs[0]()
p += 1
result = clock() - t # сразу выводить результат плохо, потому что неизвестно, сколько работы-времени тратится на поиск текущего объекта вывода (sys.stdout)
print 'example #1: %f sec.' % result
def func1():
from time import clock
local_foo = foo
## обязательно нужно создать локальную ссылку, ведь в "func" с помощью
## funcs = [foo, lambda: None]
## ускоряется доступ к функциям
p = 0
t = clock()
while p < 100000:
if p >= 0:
local_foo()
p += 1
result = clock() - t
print 'example #2: %f sec.' % result
func()
func1()
# example #1: 1.984375 sec.
# example #2: 2.125000 sec.
## При лучших тестах второй пример отстает всего на несколько сотых, но у меня чаще наблюдается именно такое отставание, где-то полторы-две десятых.
## Несущественное, имхо.
# wbr, Virtuos86
Прикрепленный файл #1: 452_synthetic_tests.zip | скачать с зеркала | (967 b)
-------------
добавлено в 02.43: '%s' % str(obj) лишняя писанина
%s сам по себе говорит, что к объекту нужно применить функцию str и результат поместить в строку: '%s' % obj
Так же как %r намекает на repr.
А вот уже %d, %i и %f требуют всенепременно число.
---
Да и тесты-то синтетические. В реале редко 100500 раз вызываешь в цикле функцию. Нужно в каждом конкретном случае решать, сэкономить на лишнем коде, или на скорости его выполнения. Редко более краткий вариант бывает более быстрым. За исключением встроенных функций и модулей расширений, ну и списковых встраиваний.
#простой Python-скрипт, который извлекает веб-страницу, парсит ее на наличие URL-ссылок и выводит на экран первые 10 из них.
import re
import urllib
regex = re.compile(r'href="([^"]+)"')
def matcher(url, max=10):
data = urllib.urlopen(url).read()
hits = regex.findall(data)
for hit in hits[:max]:
print urllib.basejoin(url, hit)
matcher("https://dimonvideo.ru")
Прикрепленный файл #1: 762_url_parser.zip | скачать с зеркала | (455 b)
Zaterehniy, а если я вот так на хтмл странице ссылку напишу -
"<a href=\'https://sajt.ru\'>ссылка</a>"?
Или вообще без кавычек - большинство браузеров нормально отображают такие синтаксические ошибки...
regex = re.compile(r'href=[\"\']?([^\"\'<>]+)[\"\']?\s')
WyTHuK_proxy,
import time, appuifw
t=time.clock()
map(str, range(10000))
t1 = time.clock() - t
t = time.clock()
[str(i) for i in range(10000)]
t2 = time.clock() - t
appuifw.app.body=appuifw.Text(u'map: %s\nfor: %s' % (t1, t2))
map: 0.640625
for: 1.015625
В мапе ты применяешь функцию ко всем элементам последовательности, а в цикле ты сначала присваиваешь значение i, потом извлекаешь и применяешь к нему функцию.
несомненно map(f, range) быстрее чем просто range , но быстрее map(f, range) часто работает простой xrange,
но все же самый быстрый способ обрабатывать НЕИЗМЕНЯЕМЫЕ последоваотдельности это map(f, xrange)...
а что касается цикла range он необходим в программировании т.к при for i in (x)range(integer):
в теле цикла значение i можно изменить тем самым пропустив Н шагов цикла.
цикл map такой возможности лишен, что говорит о его минимальной гибкости за счет большей скорости.
Такая ситуация.
Есть проект.
Он разбит на несколько модулей.
Есть какие-то функции (а может и модули), которые используются в нескольких модулях проекта.
Например, привычная функция ru:
def ru(t):
return t.decode('utf8')
Чтобы избежать дублирования кода, можно пойти следующим путём: создать один некий модуль General, куда поместить весь общий код.
Далее в модулях проекта пишем
from General import *
или
import General
кому как нравится,
и все дела.
Если подобного кода много, то это наиболее приемлемый вариант.
А если нужно лишь "обобщить" всего одну-две функции, типа той же ru?
Неплохим выходом будет такой финт ушами:
Определяем в главном модуле проекта (default.py например) функцию ru и "обобщаем" её:
import __builtin__
__builtin__.ru = ru
del __builtin__
или
__import__(__builtin__).ru = ru
То есть мы помещаем ссылку на функцию во встроенное пространство имён (ВПИ), доступ к которому предоставляет модуль __builtin__.
Плюсы:
.* ВПИ всегда доступно без явного импорта
.* нет лишнего файла
Предлагаю функцию проверки есть ли в тексте английские и русские слова. Только что написал, может с багами.
# -*- coding: utf-8 -*-
#Check_language.py, by Krust (09, 06, 2011)
def check(text):
text=text.split()
result=0
for word in text:
lang_word=0 # язык слова
for b in word:
l_b=0 # язык буквы
cod=ord(b)
if 64l_b=1
elif 1039l_b=2 # ru
if lang_word and lang_word !=l_b:
lang_word=0
break
lang_word=l_b
result|=lang_word
if result==3:break
return result
def ru(t):return t.decode('u8')
print check(ru('привет name'))
# 1-есть английские слова, 2-есть русские, 3-есть из обоих
Прикрепленный файл #1:
-------------
добавлено в 03.35: Эт просто ща делал для автоперевода буфера обмена (файл проверяется раз в секунду на время изменения) в гугле
-------------
добавлено в 03.44: Да- в демоне re и urllib накладно юзать.
- «
- 1
- 2
- 3
- 4
- --
- 8
- 9
- »