这句话在python 符号含义中的含义 2 * [1, -1][j % 2]

Python3.x和Python2.x的区别_百度知道
Python3.x和Python2.x的区别
提问者采纳
&&gt.x版本是返回伪随机布尔值的
6)__getslice__系列成员被废弃, in &lt.items 和,
bytes&#39.split(b’ ‘)来达到相同目的
3)zip(),必须显式调用;&gt.decode()
&gt, b。主要的入口点不再是generate_tokens,抛出TypeError异常:
.X的方式如下,请使用/;) 4)__name__&#39,请参阅 PEP 3119和PEP 3141: print
# 输出新行
3, **kwds).x版本的unicode几乎一样;0b&#39.x和2,请参阅“数据类型”的第2条目
5.es/programacion/&quot,而且我安装的是Python3、coerce(),在Py2;0b'&&gt,在Py2;
&&gt。使用noclocal x可以直接指派外围(非全局)变量
6)去除print语句;&gt, 1.X;&gt: print(&quot.0a1版本中没有实现
8;&gt.X.1性能比Py2。
# 输出repr((x;&gt。特此在自己的空间中记录一下. except NotImplementedError.面向对象
1)引入抽象基类(Abstraact Base Classes,因为__context__在3, 2*2)
2, popen2.:j]根据上下文转换为a;&0b' s =)
# 使用空格代替换行
2: print(&quot,定义一个bytes字面量的方法如下;&china'& @foo
class C(object).X, *rest = seq和 *rest,已经改为exec()函数
例如; D(8)
&,可以从Error' type(b)
& list(range(10))
[0,要得到整型结果。2。a[i.es/programacion/&gt, file=&gt:
&fatal error&quot, 9]
2)bytes对象不能hash,也不支持
12)扩展的可迭代解包;&
&&&gt,但它的行为就像2:
def print_func(self);china&#39,用 in替代它吧
&gt、reduce()和reload
()函数都被去除了 现在可以使用hasattr()来替换 callable(), a)。最终我们将会有一个透明高效的模块; import collections
&print(中国)
3.0运行 pystone benchmark的速度比Py2,
3)dict的;)) # 读取键盘输入的方法
3, a), &quot:
&gt,全部改用;&y;f’)和b.htm获取)
5)移除了new模块
6)&gt. 字符串和字节串
1)现在字符串只有str一种类型, Bastion。Guido认为Py3;& 0o666
&gt.jcea.1, mimify, line 1)
& str)方法相互转化:// file
Traceback (most recent call last).5多了很多,当x和y类型不匹配时抛出TypeError而不是返回随即的 bool值
8)输入函数改变了;&gt.keys().strip()和b, 6:
2,这就使得以下代码是合法的:guess = int(raw_input(&#39,现在只有一种整型——The answer is&quot.X, 5.encode() (str -&gt.; 0666
SyntaxError.; 0666
&&gt: print &quot.X:
&gt.stderr)
2;n\ bin(438)
'&gt:guess = int(input('
在Py3;&gt.has_key()://www:
def __init__(self, world, sunaudiodev!
class decorator可以用来玩玩狸猫换太子的大把戏;&fatal error& file
& class D(C);Enter an integer .;&gt:
2;C&#39.X.;\。
Py3,而是 tokenize,F y的不能比较;&gt.tokenize()
9;&The answer is&quot. hasattr()的语法如;&gt: print &&gt:
def __init(&gt,Error&#39。同时去掉的还有
dict: &#39,全部改用repr()
3)关键词加入as 和with,用以调用迭代器的__next__()方法
4)增加了@abstractmethod和 @abstractproperty两个 decorator这个星期开始学习Python了;__main__, c)); _438
'&gt,特意在Google上search了一下3。
2)容器类和迭代器类被ABCs化
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁python(4)
晚上废了一个来小时才终于搞完了。。。。中间碰到无数的问题 主要是由于 python版本的问题,网上的好多爬虫教程都是用的python2 而python3相对于python2感觉改了好多=.=
python3的urllib2不叫这个名字了,改成了urllib.request
还有urlopen.read函数返回的不再是string 而是byte 需要在后面加上句decode('utf-8') 这个调了好久=.=
def getHtml(url):
page = urllib.request.urlopen(url)
html = page.read()
return html.decode('utf-8')
再就是正则表达了,本来只是打算爬一下贴吧上的图片,但是正则表达式也是调了好久才勉强说得过去
主要是本来只想爬jpg结尾的图片没想到出现这么一种特殊情况。。。真蛋疼。。
/tb/cms/img/tieba_index_banner960x90.png&/&&/a&&/div&
&div id=&container& class=&l_container
&&&div class=&content clearfix&&&div class=&card_top_wrap clearfix card_top_theme2 & &&div class=&card_top_right&&
&div class=&sign_mod_bright& id=&sign_mod&&&div class=&sign_tip_container&&&div class=&j_succ_info sign_succ1& style=&display:none&&&div class=&sign_tip_bdwrap clearfix&&&div class=&sign_tip_bd_arr&&&/div&&div class=&sign_tip_main&&&div class=&sign_succ_calendar&&&div class=&sign_succ_calendar_title&&&div class=&calendar_title_month clearfix&&&div class=&calendar_month_next j_calendar_month_next&& &/div&&div class=&calendar_month_prev j_calendar_month_prev&& &/div&&div class=&calendar_month_span j_calendar_month&& &/div&&/div&&/div&&table class=&sign_succ_table &
&&thead align=&center&&&tr class=&sign_succ_canlerdar_head&&&td&日&/td&&td&一&/td&&td&二&/td&&td&三&/td&&td&四&/td&&td&五&/td&&td&六&/td&&/tr&&/thead&&tbody align=&center& class=&sign_succ_canlerdar_days j_canlerdar_days&&&tr&&td class=&j_1_0&& &/td&&td class=&j_1_1&& &/td&&td class=&j_1_2&& &/td&&td class=&j_1_3&& &/td&&td class=&j_1_4&& &/td&&td class=&j_1_5&& &/td&&td class=&j_1_6&& &/td&&/tr&&tr&&td class=&j_2_0&& &/td&&td class=&j_2_1&& &/td&&td class=&j_2_2&& &/td&&td class=&j_2_3&& &/td&&td class=&j_2_4&& &/td&&td class=&j_2_5&& &/td&&td class=&j_2_6&& &/td&&/tr&&tr&&td class=&j_3_0&& &/td&&td class=&j_3_1&& &/td&&td class=&j_3_2&& &/td&&td class=&j_3_3&& &/td&&td class=&j_3_4&& &/td&&td class=&j_3_5&& &/td&&td class=&j_3_6&& &/td&&/tr&&tr&&td class=&j_4_0&& &/td&&td class=&j_4_1&& &/td&&td class=&j_4_2&& &/td&&td class=&j_4_3&& &/td&&td class=&j_4_4&& &/td&&td class=&j_4_5&& &/td&&td class=&j_4_6&& &/td&&/tr&&tr class=&j_5& style=&display:none&&&td class=&j_5_0&& &/td&&td class=&j_5_1&& &/td&&td class=&j_5_2&& &/td&&td class=&j_5_3&& &/td&&td class=&j_5_4&& &/td&&td class=&j_5_5&& &/td&&td class=&j_5_6&& &/td&&/tr&&tr class=&j_6& style=&display:none&&&td class=&j_6_0&& &/td&&td class=&j_6_1&& &/td&&td class=&j_6_2&& &/td&&td class=&j_6_3&& &/td&&td class=&j_6_4&& &/td&&td class=&j_6_5&& &/td&&td class=&j_6_6&& &/td&&/tr&&/tbody&&/table&&/div&&div class=&sign_tip_boards&&&div class=&sign_tip_board sign_tip_board_urank j_sign_ad_mobi&&&div class=&sign_tip_board_ico&&&/div&&p&签到排名:今日本吧第&span class=&sign_index_num j_signin_index&&&/span&个签到,&/p&&p&&span class=&j_succ_text&&本吧因你更精彩,明天继续来努力!&/span&&/p&&/div&&div class=&sign_tip_board sign_tip_board_barrank&&&div class=&sign_tip_board_ico&&&/div&
&p&本吧签到人数:0&/p&&/div&&/div&&/div&&div class=&sign_tip_aside&&
&div class=&sign_tip_sbox sign_tip_sbox_first sign_tip_sbox_1key&&&div class=&sign_tip_sbox_hd&&一键签到&/div&&div class=&sign_tip_sbox_bd&&&div class=&sign_tip_sbox_cnt&&&a class=&sign_tip_sbox_card j_sign_tip_1key_icon sign_tip_sbox_card_pencil& href=&/tbmall/tshow?tab=detail& target=&_blank&&&/a&&div class=&sign_tip_sbox_txt&&可签&span class=&orange_text&&7&/span&级以上的吧&span class=&orange_text&&50&/span&个&/div&&div class=&sign_tip_sbox_btn&&&a href=&/home/main?id=#stipsign& target=&_blank& class=&ui_btn ui_btn_sub_s&&&span&&em&&b class=&sign_crown sign_crown_pencil& title=&无瑕的T秀勋章&&&/b&一键签到&/em&&/span&&/a&&/div&&/div&&/div&&/div&
&div class=&sign_tip_sbox sign_tip_sbox_fixsign&&&div class=&sign_tip_sbox_hd sign_tip_sbox_hd_inf j_need_rpln_wrap&&本月漏签&span class=&j_lack_sign_monthly_count sign_num&&0&/span&次!&/div&&div class=&sign_tip_sbox_bd&&&div class=&sign_tip_sbox_cnt&&&a href=&/tbmall/propslist?category=108& class=&sign_tip_sbox_card& target=&_blank&&&span class=&sign_num&&&span class=&j_rpln_card_count&&0&/span&&/span&&/a&&div class=&sign_tip_sbox_txt&&成为超级会员,赠 送8张补签卡&/div&&div class=&sign_tip_sbox_btn&&&a href=&#& class=&ui_btn ui_btn_sub_s j_lack_sign_monthly_help& target=&_blank&&&span&&em&如何使用?&/em&&/span&&/a&&div class=&lack_sign_monthly_tip_wrap&&&div class=&ui_card_wrap lack_sign_monthly_tip_card j_lack_sign_monthly_tip_card& style=&display:&&&div class=&ui_card_content &&&div class=&time_gift_tip&&点击日历上漏签日期,即可进行&span class=&strongerText&&补签&/span&。&/div&&/div&&span class=&arrow ui_white_down& style=&left:48%;&&&/span&&/div&&/div&&/div&&/div&&/div&&/div&&div class=&sign_tip_sbox sign_tip_sbox_chainsign&&&div class=&sign_tip_sbox_hd sign_tip_sbox_hd_inf&&连续签到:&span class=&sign_num j_sign_succ_keep&&&/span&天  累计签到:&span class=&sign_num j_sign_succ_count&&&/span&天&/div&&div class=&sign_tip_sbox_bd&&&div class=&sign_tip_sbox_cnt&&&a href=&/tbmall/propslist?category=108& class=&sign_tip_sbox_card& target=&_blank&&&span class=&sign_num&&&span class=&j_sign_chainsign_num&&0&/span&&/span&&/a&&div class=&sign_tip_sbox_txt&&超级会员单次开通12个月以上,赠送连续签到卡3张&/div&&div class=&sign_tip_sbox_btn&&&a href=&#& class=&ui_btn ui_btn_sub_s j_cont_sign_card& target=&_blank&&&span&&em&使用连续签到卡&/em&&/span&&/a&&/div&&/div&&/div&&/div&&div class=&sign_tip_sbox sign_tip_sbox_last sign_tip_sbox_rights&&&div class=&sign_tip_sbox_bd j_sign_rights&&&div class=&sign_rights_display clearfix&&&div class=&sign_rights_icon j_sign_rights_icon rights_1&&&/div&&div class=&sign_rights_icon j_sign_rights_icon rights_2&&&/div&&div class=&sign_rights_icon j_sign_rights_icon rights_3&&&/div&&div class=&sign_rights_icon j_sign_rights_icon rights_4&&&/div&&div class=&sign_rights_icon j_sign_rights_icon rights_5&&&/div&&span class=&split_line&&&/span&&a href=&/f/like/level?kw=%E6%81%B6%E9%AD%94&ie=utf-8&lv_t=lv_nav_who& class=&balv_help& title=&签到规则& target=&_blank&&&/a&&/div&&/div&&/div&&/div&
&/div&&/div&&/div&&div id=&signstar_wrapper& class=&j_sign_box sign_box_bright& &&a href=&#& onclick=&return false& data-dw=&5& tabindex=&3& title=&签到& class=&j_signbtn sign_btn_bright& &&span class=&sign_today_date&&02月05日&/span&&span class=&sign_month_lack_days&&漏签&span class=&j_sign_month_lack_days&&0&/span&天&/span&&/a&&/div&
&/div&&/div&&div class=&card_top
clearfix&&
&div class=&card_head &&&a href=&/f?kw=%E6%81%B6%E9%AD%94&ie=utf-8&&
&img class=&card_head_img& src=&/timg?wapp&quality=80&size=b150_150&subsize=20480&cut_x=0&cut_w=0&cut_y=0&cut_h=0&sec=&srctrace&di=8e019dfa8f3078bf8ddc&wh_rate=null&src=http%3A%2F%%2Fforum%2Fpic%2Fitem%2Fcf3d7caf096bf27f31fbe096b63a97b.jpg
特么的还真是以src=开头的 以jpg结尾的。。
这是原来的正则表达式:
r = r'src=&(.*?\.jpg)&'
修改之后勉强能说的过去吧,唯一的瑕疵就是扒下来的是个二维的元组 里面那一维的第一个是图片网址 第二个是.jpg &.gif .png啥的
import urllib.request
def getHtml(url):
page = urllib.request.urlopen(url)
html = page.read()
return html.decode('utf-8')
url = &/p/&
r = r'src=&(.*?\.(jpg|png|gif))&'
com = re.compile(r)
html = getHtml(url)
ans = com.findall(html)
for img in ans:
urllib.request.urlretrieve(img[0], 'G:/lala/%d.jpg' % num)
#下载 注意第二个参数一定要写文件名 不然报错
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:955次
排名:千里之外
原创:48篇
(3)(21)(6)(8)(12)IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
从本文展示的几个小型基准测试可以得出:通过优化 Python 代码以及借助各种可用于让代码更快运行的 Python 工具,能够使 Python 的性能与 Julia 的性能不相上下。
, 首席架构师,
Jean Francois Puget,IBM 分析解决方案首席结构师。
Julia 与 Python
的比较我是否应丢弃 Python 和其他语言,使用 Julia 执行技术计算?在看到
上的基准测试后,人们一定会这么想。Python
和其他高级语言在速度上远远有些落后。但是,我想到的第一个问题有所不同:Julia 团队能否以最适合 Python 的方式编写 Python 基准测试?我对这种跨语言比较的观点是,应该根据要执行的任务来定义基准测试,然后由语言专家编写执行这些任务的最佳代码。如果代码全由一个语言团队编写,则存在其他语言未得到最佳使用的风险。Julia 团队有一件事做得对,那就是他们将发布到了 github 上。具体地讲,Python 代码可在找到。第一眼看到该代码,就可以证实我所害怕的偏见。该代码是以 C 风格编写的,在数组和列表上大量使用了循环。这不是使用 Python 的最佳方式。我不会责怪 Julia 团队,因为我很内疚自己也有同样的偏见。但我受到了残酷的教训:付出任何代价都要避免数组或列表上的循环,因为它们确实会拖慢 Python
中的速度,请参阅 。考虑到对 C 风格的这种偏见,一个有趣的问题(至少对我而言)是,我们能否改进这些基准测试,更好地使用 Python 及其工具?在我给出答案之前,我想说我绝不会试图贬低 Julia。在进一步开发和改进后,Julia 无疑是一种值得关注的语言。我只是想分析 Python
方面的事情。实际上,我正在以此为借口来探索各种可用于让代码更快运行的 Python 工具。在下面的内容中,我使用 在 Jupyter Notebook 中使用 Python 3.4.3,其中已安装了所有的 Python 科学工具组合。我还会通过
Windows 机器上的 Python 2.7.10,使用
来运行代码。计时是对 Python 3.4.3 执行的。包含下面的所有基准测试的完整代码的 Notebook 可在找到。鉴于各种社交媒体上的评论,我添加了这样一句话:我没有在这里使用 Python 的替代性实现。我没有编写任何 C
代码:如果您不信,可试试寻找分号。本文中使用的所有工具都是 Anaconda 或其他发行版中提供的标准的 Cython 实现。下面的所有代码都在中运行。我尝试过使用来自
的 Julia 微性能文件,但不能使用 Julia 0.4.2 原封不动地运行它。我必须编辑它并将 @timeit 替换为
@time,它才能运行。在对它们计时之前,我还必须添加对计时函数的调用,否则编译时间也将包含在内。我使用的文件位于。我在用于运行 Python 的同一个机器上使用 Julia 命令行接口运行它。计时代码Julia 团队使用的第一项基准测试是 Fibonacci 函数的一段简单编码。def fib(n):
return fib(n-1)+fib(n-2)此函数的值随 n 的增加而快速增加,例如:fib(100) = 可以注意到,Python 任意精度 (arbitrary precision) 很方便。在 C 等语言中编写相同的函数需要花一些编码工作来避免整数溢出。在 Julia
中,需要使用 BigInt 类型。所有 Julia 基准测试都与运行时间有关。这是 Julia 中使用和不使用 BigInt 的计时: 0.000080 seconds (149 allocations:10.167 KB)
0.012717 seconds (262.69 k allocations:4.342 MB)在 Python Notebook 中获得运行时间的一种方式是使用神奇的 %timeit。例如,在一个新单元中键入:%timeit fib(20)执行它会获得输出:100 loops, best of 3:3.33 ms per loop这意味着计时器执行了以下操作: 运行 fib(20) 100 次,存储总运行时间 运行 fib(20) 100 次,存储总运行时间 运行 fib(20) 100 次,存储总运行时间 从 3 次运行中获取最小的运行时间,将它除以 100,然后输出结果,该结果就是 fib(20) 的最佳运行时间这些循环的大小(100 次和 3 次)会由计时器自动调整。可能会根据被计时的代码的运行速度来更改循环大小。Python 计时与使用了 BigInt 时的 Julia 计时相比出色得多:3 毫秒与 12 毫秒。在使用任意精度时,Python 的速度是 Julia 的 4
倍。但是,Python 比 Julia 默认的 64 位整数要慢。我们看看如何在 Python 中强制使用 64 位整数。使用 Cython 编译一种编译方式是使用
编译器。这个编译器是使用 Python
编写的。它可以通过以下命令安装:pip install Cython如果使用 Anaconda,安装会有所不同。因为安装有点复杂,所以我编写了一篇相关的博客文章:安装后,我们使用神奇的 %load_ext 将 Cython 加载到 Notebook 中:%load_ext Cython然后就可以在我们的 Notebook 中编译代码。我们只需要将想要编译的代码放在一个单元中,包括所需的导入语句,使用神奇的 %%cython 启动该单元:%%cython
def fib_cython(n):
return fib_cython(n-1)+fib_cython(n-2)执行该单元会无缝地编译这段代码。我们为该函数使用一个稍微不同的名称,以反映出它是使用 Cython
编译的。当然,一般不需要这么做。我们可以将之前的函数替换为相同名称的已编译函数。对它计时会得到:1000 loops, best of 3:1.22 ms per loop哇,几乎比最初的 Python 代码快 3 倍!我们现在比使用 BigInt 的 Julia 快 100 倍。我们还可以尝试静态类型。使用关键字 cpdef 而不是 def 来声明该函数。它使我们能够使用相应的 C 类型来键入函数的参数。我们的代码变成了:%%cython
cpdef long fib_cython_type(long n):
return fib_cython_type(n-1)+fib_cython_type(n-2)执行该单元后,对它计时会得到:10000 loops, best of 3:36 us per loop太棒了,我们现在只花费了 36 微秒,比最初的基准测试快约 100 倍!这与 Julia 所花的 80 毫秒相比更出色。有人可能会说,静态类型违背了 Python
的用途。一般来讲,我比较同意这种说法,我们稍后将查看一种在不牺牲性能的情况下避免这种情形的方法。但我并不认为这是一个问题。Fibonacci
函数必须使用整数来调用。我们在静态类型中失去的是 Python 所提供的任意精度。对于 Fibonacci,使用 C 类型 long
会限制输入参数的大小,因为太大的参数会导致整数溢出。请注意,Julia 计算也是使用 64 位整数执行的,因此将我们的静态类型版本与 Julia 的对比是公平的。缓存计算我们在保留 Python 任意精度的情况下能做得更好。fib 函数重复执行同一种计算许多次。例如,fib(20) 将调用 fib(19) 和
fib(18)。fib(19) 将调用 fib(18) 和 fib(17)。结果 fib(18) 被调用了两次。简单分析表明,fib(17) 将被调用 3
次,fib(16) 将被调用 5 次,等等。在 Python 3 中,我们可以使用 functools 标准库来避免这些重复的计算。from functools import lru_cache as cache
@cache(maxsize=None)
def fib_cache(n):
return fib_cache(n-1)+fib_cache(n-2)对此函数计时会得到:1000000 loops, best of 3:910 ns per loop速度又增加了 40 倍,比最初的 Python 代码快约 3,600 倍!考虑到我们仅向递归函数添加了一条注释,此结果非常令人难忘。Python 2.7 中没有提供这种自动缓存。我们需要显式地转换代码,才能避免这种情况下的重复计算。def fib_seq(n):
for i in range(n-1):
a,b = a+b,a
return a请注意,此代码使用了 Python 同时分配两个局部变量的能力。对它计时会得到:1000000 loops, best of 3:1.77 us per loop我们又快了 20 倍!让我们在使用和不使用静态类型的情况下编译我们的函数。请注意,我们使用了 cdef 关键字来键入局部变量。%%cython
def fib_seq_cython(n):
for i in range(n-1):
a,b = a+b,a
cpdef long fib_seq_cython_type(long n):
cdef long a,b
for i in range(n-1):
a,b = a+b,b
return a我们可在一个单元中对两个版本计时:%timeit fib_seq_cython(20)
%timeit fib_seq_cython_type(20)结果为:1000000 loops, best of 3:953 ns per loop
loops, best of 3:51.9 ns per loop静态类型代码现在花费的时间为 51.9 纳秒,比最初的基准测试快约 60,000(六万)倍。如果我们想计算任意输入的 Fibonacci 数,我们应坚持使用无类型版本,该版本的运行速度快 3,500 倍。还不错,对吧?使用 Numba 编译让我们使用另一个名为
的工具。它是针对部分 Python 版本的一个即时
(jit) 编译器。它不是对所有 Python 版本都适用,但在适用的情况下,它会带来奇迹。安装它可能很麻烦。推荐使用像
这样的 Python 发行版或一个已安装了 Numba 的 。完成安装后,我们导入它的 jit 编译器:from numba import jit它的使用非常简单。我们仅需要向想要编译的函数添加一点修饰。我们的代码变成了:@jit
def fib_seq_numba(n):
(a,b) = (1,0)
for i in range(n-1):
(a,b) = (a+b,a)
return a对它计时会得到:1000000 loops, best of 3:225 ns per loop比无类型的 Cython 代码更快,比最初的 Python 代码快约 16,000 倍!使用 Numpy我们现在来看看第二项基准测试。它是快速排序算法的实现。Julia 团队使用了以下 Python 代码:def qsort_kernel(a, lo, hi):
while i & hi:
pivot = a[(lo+hi) // 2]
while i &= j:
while a[i] & pivot:
while a[j] & pivot:
if i &= j:
a[i], a[j] = a[j], a[i]
if lo & j:
qsort_kernel(a, lo, j)
return a我将他们的基准测试代码包装在一个函数中:import random
def benchmark_qsort():
lst = [ random.random() for i in range(1,5000) ]
qsort_kernel(lst, 0, len(lst)-1)对它计时会得到:100 loops, best of 3:18.3 ms per loop上述代码与 C 代码非常相似。Cython 应该能很好地处理它。除了使用 Cython 和静态类型之外,让我们使用 Numpy
数组代替列表。在数组大小较大时,比如数千个或更多元素, 数组确实比
Python 列表更快。安装 Numpy 可能会花一些时间,推荐使用
或一个已安装了 Python 科学工具组合的 。在使用 Cython 时,需要将 Numpy 导入到应用了 Cython 的单元中。在使用 C 类型时,还必须使用 cimport 将它作为 C 模块导入。Numpy
数组使用一种表示数组元素类型和数组维数(一维、二维等)的特殊语法来声明。%%cython
import numpy as np
cimport numpy as np
cpdef np.ndarray[double, ndim=1] \
qsort_kernel_cython_numpy_type(np.ndarray[double, ndim=1] a, \
long lo, \
double pivot
while i & hi:
pivot = a[(lo+hi) // 2]
while i &= j:
while a[i] & pivot:
while a[j] & pivot:
if i &= j:
a[i], a[j] = a[j], a[i]
if lo & j:
qsort_kernel_cython_numpy_type(a, lo, j)
cpdef benchmark_qsort_numpy_cython():
lst = np.random.rand(5000)
qsort_kernel_cython_numpy_type(lst, 0, len(lst)-1)对 benchmark_qsort_numpy_cython() 函数计时会得到:1000 loops, best of 3:1.32 ms per loop我们比最初的基准测试快了约 15 倍,但这仍然不是使用 Python 的最佳方法。最佳方法是使用 Numpy 内置的 sort()
函数。它的默认行为是使用快速排序算法。对此代码计时:def benchmark_sort_numpy():
lst = np.random.rand(5000)
np.sort(lst)会得到:1000 loops, best of 3:350 us per loop我们现在比最初的基准测试快 52 倍!Julia 在该基准测试上花费了 419 微秒,因此编译的 Python 快 20%。我知道,一些读者会说我不会进行同类比较。我不同意。请记住,我们现在的任务是使用主机语言以最佳的方式排序输入数组。在这种情况下,最佳方法是使用一个内置的函数。剖析代码我们现在来看看第三个示例,计算 Mandelbrodt 集。Julia 团队使用了这段 Python 代码:def mandel(z):
maxiter = 80
for n in range(maxiter):
if abs(z) & 2:
z = z*z + c
return maxiter
def mandelperf():
r1 = np.linspace(-2.0, 0.5, 26)
r2 = np.linspace(-1.0, 1.0, 21)
return [mandel(complex(r, i)) for r in r1 for i in r2]
assert sum(mandelperf()) == 14791最后一行是一次合理性检查。对 mandelperf() 函数计时会得到:100 loops, best of 3:4.62 ms per loop使用 Cython 会得到:100 loops, best of 3:1.94 ms per loop还不错,但我们可以使用 Numba 做得更好。不幸的是,Numba 还不会编译列表推导式 (list
comprehension)。因此,我们不能将它应用到第二个函数,但我们可以将它应用到第一个函数。我们的代码类似以下代码。@jit
def mandel_numba(z):
maxiter = 80
for n in range(maxiter):
if abs(z) & 2:
z = z*z + c
return maxiter
def mandelperf_numba():
r1 = np.linspace(-2.0, 0.5, 26)
r2 = np.linspace(-1.0, 1.0, 21)
return [mandel_numba(complex(r, i)) for r in r1 for i in r2]对它计时会得到:1000 loops, best of 3:503 us per loop还不错,比 Cython 快 4 倍,比最初的 Python 代码快 9 倍!我们还能做得更好吗?要知道是否能做得更好,一种方式是剖析代码。内置的 %prun 剖析器在这里不够精确,我们必须使用一个称为
的更好的剖析器。它可以通过
pip 进行安装:pip install line_profiler安装后,我们需要加载它:%load_ext line_profiler然后使用一个神奇的命令剖析该函数:%lprun -s -f mandelperf_numba mandelperf_numba()它在一个弹出窗口中输出以下信息。Timer unit:1e-06 s
Total time:0.003666 s
File:&ipython-input-102-e&
Function: mandelperf_numba at line 11
Line # Hits Time Per Hit % Time Line Contents
==============================================================
11 def mandelperf_numba():
54.4 r1 = np.linspace(-2.0, 0.5, 26)
13 1 267 267.0 7.3 r2 = np.linspace(-1.0, 1.0, 21)
38.3 return [mandel_numba(complex(r, i)) for r in r1 for i in r2]我们看到,大部分时间都花费在了 mandelperf_numba() 函数的第一行和最后一行上。最后一行有点复杂,让我们将它分为两部分来再次剖析:def mandelperf_numba():
r1 = np.linspace(-2.0, 0.5, 26)
r2 = np.linspace(-1.0, 1.0, 21)
c3 = [complex(r, i) for r in r1 for i in r2]
return [mandel_numba(c) for c in c3]剖析器输出变成:Timer unit:1e-06 s
Total time:0.002002 s
File:&ipython-input-113-ba7b044b2c6c&
Function: mandelperf_numba at line 11
Line # Hits Time Per Hit % Time Line Contents
==============================================================
11 def mandelperf_numba():
12 1 678 678.0 33.9 r1 = np.linspace(-2.0, 0.5, 26)
13 1 235 235.0 11.7 r2 = np.linspace(-1.0, 1.0, 21)
14 1 617 617.0 30.8 c3 = [complex(r, i) for r in r1 for i in r2]
15 1 472 472.0 23.6 return [mandel_numba(c) for c in c3]我们可以看到,对函数 mandel_numba() 的调用仅花费了总时间的 1/4。剩余时间花在 mandelperf_numba()
函数上。花时间优化它是值得的。再次使用 Numpy使用 Cython 在这里没有太大帮助,而且 Numba 不适用。摆脱此困境的一种方法是再次使用 Numpy。我们将以下代码替换为生成等效结果的 Numpy
代码。 return [mandel_numba(complex(r, i)) for r in r1 for i in r2]此代码构建了所谓的二维网格。它计算由 r1 和 r2 提供坐标的点的复数表示。点 Pij 的坐标为 r1[i] 和 r2[j]。Pij 通过复数 r1[i] +
1j*r2[j] 进行表示,其中特殊常量 1j 表示单个虚数 i。我们可以直接编写此计算的代码:@jit
def mandelperf_numba_mesh():
width = 26
height = 21
r1 = np.linspace(-2.0, 0.5, width)
r2 = np.linspace(-1.0, 1.0, height)
mandel_set = np.zeros((width,height), dtype=int)
for i in range(width):
for j in range(height):
mandel_set[i,j] = mandel_numba(r1[i] + 1j*r2[j])
return mandel_set请注意,我将返回值更改为了一个二维整数数组。如果要显示结果,该结果与我们需要的结果更接近。对它计时会得到:10000 loops, best of 3:140 us per loop我们比最初的 Python 代码快约 33 倍!Julia 在该基准测试上花费了 196 微秒,因此编译的 Python 快 40%。向量化让我们来看另一个示例。老实地讲,我不确定要度量什么,但这是 Julia 团队使用的代码。def parse_int():
for i in range(1,1000):
n = random.randint(0,2**32-1)
s = hex(n)
if s[-1]=='L':
s = s[0:-1]
m = int(s,16)
assert m == n实际上,Julia 团队的代码有一条额外的指令,用于在存在末尾的 'L' 时删除它。我的 Anaconda 安装需要这一行,但我的 Python 3
安装不需要它,所以我删除了它。最初的代码是:def parse_int():
for i in range(1,1000):
n = random.randint(0,2**32-1)
s = hex(n)
if s[-1]=='L':
s = s[0:-1]
m = int(s,16)
assert m == n对修改后的代码计时会得到:100 loops, best of 3:3.33 ms per loopNumba 似乎没什么帮助。Cython 代码运行速度快了约 5 倍:1000 loops, best of 3:617 us per loopCython 代码运行速度快了约 5 倍,但这还不足以弥补与 Julia 的差距。我对此基准测试感到迷惑不解,我剖析了最初的代码。以下是结果:Timer unit:1e-06 s
Total time:0.013807 s
File:&ipython-input-3-1d&
Function: parse_int at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def parse_int():
2 .7 5.1 for i in range(1,1000):
66.3 n = random.randint(0,2**32-1)
7.4 s = hex(n)
5 999 863 0.9 6.3 if s[-1]=='L':
6 s = s[0:-1]
9.7 m = int(s,16)
8 999 738 0.7 5.3 assert m == n可以看到,大部分时间都花费在了生成随机数上。我不确定这是不是该基准测试的意图。加速此测试的一种方式是使用 Numpy 将随机数生成移到循环之外。我们一次性创建一个随机数数组。def parse_int_vec():
n = np.random.randint(0,2**32-1,1000)
for i in range(1,1000):
s = hex(ni)
m = int(s,16)
assert m == ni对它计时会得到:1000 loops, best of 3:848 us per loop还不错,快了 4 倍,接近于 Cython 代码的速度。拥有数组后,通过循环它来一次向某个元素应用 hex() 和 int() 函数似乎很傻。好消息是,Numpy 提供了一种向数组应用函数的方法,而不必使用循环,该函数是
numpy.vectorize() 函数。此函数接受一次处理一个对象的函数。它返回一个处理数组的新函数。vhex = np.vectorize(hex)
vint = np.vectorize(int)
def parse_int_numpy():
n = np.random.randint(0,2**32-1,1000)
s = vhex(n)
m = vint(s,16)
np.all(m == n)
return s此代码运行速度更快了一点,几乎像 Cython 代码一样快:1000 loops, best of 3:703 us per loop我肯定 Python 专家能够比我在这里做得更好,因为我不太熟悉 Python 解析,但这再一次表明避免 Python 循环是个不错的想法。结束语上面介绍了如何加快 Julia 团队所使用的 4 个示例的运行速度。还有 3 个例子: pisum 使用 Numba 的运行速度快 29 倍。 randmatstat 使用 Numpy 可将速度提高 2 倍。 randmatmul 很简单,没有工具可应用到它之上。包含所有 7 个示例的完整代码的 Notebook 可在获得。我们在一个表格中总结一下我们的结果。我们给出了在最初的 Python 代码与优化的代码之间实现的加速。我们还给出了对 Julia
团队使用的每个基准测试示例使用的工具。 时间以微秒为单位
Python 优化后的代码
Python 初始代码
Julia / Python 优化后的代码
Fibonacci64 位
Fib BigInt
Mandelbrodt
randmatmul
randmatstat
X 这个表格表明,在前 4 个示例中,优化的 Python 代码比 Julia 更快,后 3 个示例更慢。请注意,为了公平起见,对于
Fibonacci,我使用了递归代码。我认为这些小型的基准测试没有提供哪种语言最快的明确答案。举例而言,randmatstat 示例处理 5x5 矩阵。使用 Numpy
数组处理它有点小题大做。应该使用更大的矩阵执行基准测试。我相信,应该在更复杂的代码上对语言执行基准测试。中提供了一个不错的示例。在该文章中,Julia 似乎优于 Cython。如果我有时间,我会使用 Numba
试一下。无论如何,可以说,在这个小型基准测试上,使用正确的工具时,Python 的性能与 Julia 的性能不相上下。相反地,我们也可以说,Julia 的性能与编译后的
Python 不相上下。考虑到 Julia 不需要对代码进行任何注释或修改,所以这本身就很有趣。补充说明我们暂停一会儿。我们已经看到在 Python 代码性能至关重要时,应该使用许多工具: 使用 line_profiler 执行剖析。 编写更好的 Python 代码来避免不必要的计算。 使用向量化的操作和通过 Numpy 来广播。 使用 Cython 或 Numba 编译。使用这些工具来了解它们在哪些地方很有用。与此同时,请谨慎使用这些工具。分析您的代码,以便可以将精力放在值得优化的地方。重写代码来让它变得更快,有时会让它难以理解或通用性降低。因此,仅在得到的加速物有所值时这么做。Donald
Knuth 曾经恰如其分地提出了这条建议:“我们在 97% 的时间应该忘记较小的效率:不成熟的优化是万恶之源。”但是请注意,Knuth 的引语并不意味着优化是不值得的,例如,请查看和。Python 代码可以优化,而且应该在有意义的时间和位置进行优化。我们最后给出一个讨论我所使用的工具和其他工具的有趣文章列表:。scipy 团队的一篇简短的优化指南。其中还讨论了内存剖析。。各种剖析工具的简短介绍。. 和。来自 Jake Vanderplas
的三篇有趣的文章。在最后一篇中,他展示了如何结合使用 Python 与 Numba,得到仅比高度优化的 Fortran 代码慢 30% 的代码。 pandas 文档中的。一篇讲述如何让 pandas 代码更快的实用指南。 Cython 文档中的和。。标题不言自明。。2015 年 12 月 16 日更新。Python 3.4 拥有一个能显著加速 Fibonacci() 函数的内置缓存。我更新了这篇文章来展示它的用途。2015 年 12 月 17 日更新。在运行 Python 的相同机器上 运行 Julia 0.4.2 会导致时间增加。
参考资料 :查找丰富的操作信息、工具和项目更新,帮助您掌握开源技术并将其用于 IBM 产品。
加入 ,查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Open sourceArticleID=1025932ArticleTitle=如何让 Python 像 Julia 一样快地运行publish-date=

我要回帖

更多关于 python init 含义 的文章

 

随机推荐