Ноу хау - от мастеров на заметку » Страница 3

-

Программирование на Python



dimy44


репутация: 537
на сайте с 2006 года
сообщений: 2540

HTC One S

Евпатория

Возраст - 54

#21

Давайте проверим вышесказанное, смоделировав обе ситуации. У нас есть функция 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.

>>>


в общем, 'думайте сами, решайте сами, ...'

Virtuos86


репутация: 101
на сайте с 2008 года
сообщений: 802

где-то в России

#22

Примерчик-то не совсем корректный, dimy44, а winked? Ты же понимаешь, что сто тыщ раз вызывать конструктор пусть даже неизменяемого типа, как кортеж, влечет накладные расходы.

Вот мой примерчик в аттаче, ну и прямо здесь запостить нужно, файлы-то долго не живут:

1def foo(): pass
2 
3 
4 
5def func():
6 
7    from time import clock # локальный импорт; дергать модуль из глобальной области видимости в цикле в функции для замера производительности плохая идея
8 
9    funcs = [foo, lambda: None]
10 
11    ## если список функций "func" не локальный, то можно сделать локальную ссылку на него, тоже ускорит доступ к нему и к функциям:
12 
13    ##   local_funcs = func
14 
15    p = 0
16 
17    t= clock()
18 
19    while p < 100000:
20 
21        funcs[0]()
22 
23        p += 1
24 
25    result = clock() - t # сразу выводить результат плохо, потому что неизвестно, сколько работы-времени тратится на поиск текущего объекта вывода (sys.stdout)
26 
27    print 'example #1: %f sec.' % result
28 
29 
30 
31 
32 
33def func1():
34 
35    from time import clock
36 
37    local_foo = foo
38 
39    ## обязательно нужно создать локальную ссылку, ведь в "func" с помощью
40 
41    ## funcs = [foo, lambda: None]
42 
43    ## ускоряется доступ к функциям
44 
45    p = 0
46 
47    t = clock()
48 
49    while p < 100000:
50 
51        if p >= 0:
52 
53            local_foo()
54 
55            p += 1
56 
57    result = clock() - t
58 
59    print 'example #2: %f sec.' % result
60 
61 
62 
63func()
64 
65func1()
66 
67 
68 
69# example #1: 1.984375 sec.
70 
71# example #2: 2.125000 sec.
72 
73 
74 
75## При лучших тестах второй пример отстает всего на несколько сотых, но у меня чаще наблюдается именно такое отставание, где-то полторы-две десятых.
76 
77## Несущественное, имхо.
78 
79 
80 
81# wbr, Virtuos86


Прикрепленный файл #1: 452_synthetic_tests.zip | скачать с зеркала | (967 b)
-------------
добавлено в 02.43: '%s' % str(obj) лишняя писанина

%s сам по себе говорит, что к объекту нужно применить функцию str и результат поместить в строку: '%s' % obj

Так же как %r намекает на repr.

А вот уже %d, %i и %f требуют всенепременно число.

---

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

Zaterehniy


репутация: 704
на сайте с 2006 года
сообщений: 2504

Google Pixel 7a

Ставрополь

Возраст - 37

#23

#простой Python-скрипт, который извлекает веб-страницу, парсит ее на наличие URL-ссылок и выводит на экран первые 10 из них.



1import re
2 
3import urllib
4 
5 
6 
7regex = re.compile(r'href="([^"]+)"')
8 
9 
10 
11def matcher(url, max=10):
12 
13    data = urllib.urlopen(url).read()
14 
15    hits = regex.findall(data)
16 
17    for hit in hits[:max]:
18 
19        print urllib.basejoin(url, hit)
20 
21 
22 





Прикрепленный файл #1: 762_url_parser.zip | скачать с зеркала | (455 b)

dFactor


репутация:
на сайте с 1970 года
сообщений:

#24

Zaterehniy, а если я вот так на хтмл странице ссылку напишу -

?
Или вообще без кавычек - большинство браузеров нормально отображают такие синтаксические ошибки...
1regex = re.compile(r'href=[\"\']?([^\"\'<>]+)[\"\']?\s')

Punk_Joker


репутация: 26
на сайте с 2009 года
сообщений: 64

Nokia N9

Украина

Возраст - 30

#25

Использовать, где это возможно, функцию map() вместо for. Это дает выйгрыш в скорости выполнения кода, хоть и небольшой.

JOIN_ME


репутация:
на сайте с 1970 года
сообщений:

#26

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, потом извлекаешь и применяешь к нему функцию.

_killed_


репутация: 13
на сайте с 2009 года
сообщений: 59

HTC Incredible S

Нижний Новгород, С-Петербург

Возраст - 38

#27

несомненно map(f, range) быстрее чем просто range , но быстрее map(f, range) часто работает простой xrange,
но все же самый быстрый способ обрабатывать НЕИЗМЕНЯЕМЫЕ последоваотдельности это map(f, xrange)...
а что касается цикла range он необходим в программировании т.к при for i in (x)range(integer):
в теле цикла значение i можно изменить тем самым пропустив Н шагов цикла.
цикл map такой возможности лишен, что говорит о его минимальной гибкости за счет большей скорости.

JOIN_ME


репутация:
на сайте с 1970 года
сообщений:

#28

Ну map еще можно условно циклом считать, а range это не цикл. Первая функция работает с итераторами, вторая их создает (range - список, xrange - кортеж). Циклом является конструкция for/in.

Virtuos86


репутация: 101
на сайте с 2008 года
сообщений: 802

где-то в России

#29

Такая ситуация.
Есть проект.
Он разбит на несколько модулей.
Есть какие-то функции (а может и модули), которые используются в нескольких модулях проекта.

Например, привычная функция ru:

1def ru(t):
2    return t.decode('utf8')


Чтобы избежать дублирования кода, можно пойти следующим путём: создать один некий модуль General, куда поместить весь общий код.
Далее в модулях проекта пишем

или

кому как нравится,
и все дела.

Если подобного кода много, то это наиболее приемлемый вариант.

А если нужно лишь "обобщить" всего одну-две функции, типа той же ru?

Неплохим выходом будет такой финт ушами:
Определяем в главном модуле проекта (default.py например) функцию ru и "обобщаем" её:

1import __builtin__
2__builtin__.ru = ru
3del __builtin__

или


То есть мы помещаем ссылку на функцию во встроенное пространство имён (ВПИ), доступ к которому предоставляет модуль __builtin__.

Плюсы:
.* ВПИ всегда доступно без явного импорта
.* нет лишнего файла

Krust


репутация:
на сайте с 1970 года
сообщений:

#30

Предлагаю функцию проверки есть ли в тексте английские и русские слова. Только что написал, может с багами.

1# -*- coding: utf-8 -*-
2#Check_language.py, by Krust (09, 06, 2011)
3 
4def check(text):
5 text=text.split()
6 result=0
7 for word in text:
8 lang_word=0 # язык слова
9 for b in word:
10 l_b=0 # язык буквы
11 cod=ord(b)
12 if 64<cod></cod> l_b=1
13 elif 1039<cod or="" cod="" in=""></cod> l_b=2 # ru
14 if lang_word and lang_word !=l_b:
15 lang_word=0
16 break
17 lang_word=l_b
18 result|=lang_word
19 if result==3:break
20 return result
21 
22def ru(t):return t.decode('u8')
23 
24print check(ru('привет name'))
25 
26# 1-есть английские слова, 2-есть русские, 3-есть из обоих


Прикрепленный файл #1:
Внимание! У вас нет прав для просмотра скрытого текста.
| скачать с зеркала | (531 b)
-------------
добавлено в 03.35: Эт просто ща делал для автоперевода буфера обмена (файл проверяется раз в секунду на время изменения) в гугле
-------------
добавлено в 03.44: Да- в демоне re и urllib накладно юзать.


Яндекс.Метрика