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

-

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



dimy44


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

HTC One S

Евпатория

Возраст - 53

#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? Ты же понимаешь, что сто тыщ раз вызывать конструктор пусть даже неизменяемого типа, как кортеж, влечет накладные расходы.

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

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 раз вызываешь в цикле функцию. Нужно в каждом конкретном случае решать, сэкономить на лишнем коде, или на скорости его выполнения. Редко более краткий вариант бывает более быстрым. За исключением встроенных функций и модулей расширений, ну и списковых встраиваний.

Zaterehniy


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

Samsung m31s

Ставрополь

Возраст - 36

#23

#простой 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)

dFactor


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

#24

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

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

Punk_Joker


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

Nokia N9

Украина

Возраст - 29

#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

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

Возраст - 37

#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:

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__.

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

Krust


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

#30

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


# -*- 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 64 l_b=1
elif 1039 l_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:
Внимание! У вас нет прав для просмотра скрытого текста.
| скачать с зеркала | (531 b)
-------------
добавлено в 03.35: Эт просто ща делал для автоперевода буфера обмена (файл проверяется раз в секунду на время изменения) в гугле
-------------
добавлено в 03.44: Да- в демоне re и urllib накладно юзать.


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