比较Speed Python3和Julia

比较Speed Python3和Julia,第1张

概述我开始编写一个程序进行非线性光束计算.我之所以选择 Python是因为它的Matlab就像代码一样,而且我正在进行速度测试(确保python是正确的语言来进行快速数值计算)并尝试熟悉python3. 我尝试了一种算法,计算从t = 1到n的1 / t ^ 2之和(来自书Julia High Perfromance),以比较python3与julia的速度. 现在我有一些问题: 1)在我的计算中,朱 我开始编写一个程序进行非线性光束计算.我之所以选择 Python是因为它的Matlab就像代码一样,而且我正在进行速度测试(确保python是正确的语言来进行快速数值计算)并尝试熟悉python3.
我尝试了一种算法,计算从t = 1到n的1 / t ^ 2之和(来自书Julia High Perfromance),以比较python3与julia的速度.
现在我有一些问题:

1)在我的计算中,朱莉娅没有预期的那么快? Julia ist JIT编译.它应该非常快.为什么python更快?

2)为什么python中的循环如此缓慢?

3)为什么python sum方法比numpy.sum方法慢

4)为什么python geting的sum函数与numpy.sum函数的解决方案略有不同?

我希望你能帮助我.

代码:

# Benchmark Python vs Julia# (from Julia High Performance page 7 from Avik Sengupta)import scipy as spimport time# Sum of 1/t^2 from t = 1 to n by using loops:# --------------------------------------------def pisum(w,n):    u_sum = 0    for vi in range(w):        u_sum = 0        for vj in range(1,n+1,1):            u_sum += 1.0/(vj*vj)    return u_sum# Sum of 1/t^2 from t = 1 to n by using scipy functions:# ------------------------------------------------------def pisum1(w,n):    for vi in range(w):        vj = sp.arange(1,1)        vj = sp.multiply(vj,vj)        u_sum_sp = (sp.divIDe(sp.ones(n),vj)).sum()    return u_sum_sp# Sum of 1/t^2 from t = 1 to n by using scipy functions & calculating # the sum via pure python:# -------------------------------------------------------------------def pisum2(w,vj)        u_sum_py = sum(sp.divIDe(sp.ones(n),vj))    return u_sum_py# Benchmarking the methods :# ==========================   w = 500 n = 10000# 1) Loops:# ---------    ta = time.clock()u_sum_loops = pisum(w,n)eltime_loops = time.clock() - ta# 2) scipy:# ---------ta = time.clock()u_sum_sp = pisum1(w,n)eltime_sp= time.clock() - ta# 3) scipy & sum via python:# --------------------------ta = time.clock()u_sum_py = pisum2(w,n)eltime_py= time.clock() - ta# Julia with loops:# -----------------eltime_ju_loops = 0.150857295u_sum_ju = 1.6448340718480652row_format = '{:<35} {:<5} {:<5} {:<} {:<}'print("OvervIEw calculation time:")print("-"*50)print(row_format.format("elapsed time using loops:","%.5f" % eltime_loops,"sec. (","%.2f"% (eltime_loops/eltime_ju_loops),"*time Julia)"))print(row_format.format("elapsed time using scipy:","%.5f" % eltime_sp,"%.2f"% (eltime_sp/eltime_ju_loops),"*time Julia)"))print(row_format.format("elapsed time using python:","%.5f" % eltime_py,"%.2f"% (eltime_py/eltime_ju_loops),"*time Julia)"))print(row_format.format("elapsed time using Julia and loops:","%.5f" % eltime_ju_loops,"sec.","","\n"))line1 = "sum loops:",u_sum_loopsline2 = "sum scipy:",u_sum_spline3 = "sum scipy and sum via python:",u_sum_pyline4 = "sum_julia:",u_sum_jurow_format = '{:<29} {:<18}'print("OvervIEw Sum:")print("-"*50)print(row_format.format(*line1))print(row_format.format(*line2))print(row_format.format(*line3))print(row_format.format(*line4))# Julia Code:# ===========# function pisum(w,n)#     u_sum = 0;#     for vi = 1:w#         u_sum = 0;#         for vj = 1:n#             u_sum += 1.0/(vj*vj);#         end#     end#     u_sum# end# # tic()# u_sum = pisum(500,10000)# eltime = toc()
解决方法

1) In my calculations Julia is not as fast as expected? Julia ist JIT compiled. It should be very fast. Why ist python faster?

你的功能不是类型稳定的.由于它的JIT编译器,Julia并不快:因为它的类型系统它很快.它的类型系统被设计为在类型稳定函数(输出类型是输入类型的函数的函数)上使用多个调度,以在代码的每个阶段完全推导出类型,从而允许其函数基本上静态编译.通过这样做,通过将类型稳定函数链接在一起构建的函数本身可以通过类型稳定,并且与您想要编写的C / Fortran代码相比编译为1x(因为这对于所有人来说都是足够的信息)相关的编译器优化).这将在at this blog post中更详细地解释.

所以类型稳定的代码是:

function pisum(w,n)    u_sum = 0.0;    for vi = 1:w        u_sum = 0.0;        for vj = 1:n            u_sum += 1.0/(vj*vj);        end    end    u_sumend@time u_sum = pisum(500,10000)

对我而言,这个时间大约为0.02秒,比SciPy示例快2倍,比计算机上的其他实现快50倍-100倍.

请注意,您可以通过调用@code_warntype pisum(500,10000)来检查类型稳定性,这将是大写和红色突出显示返回类型不是类型稳定的行.这将向您显示您的版本将u_sum作为Int启动,然后转换为float64.想想你是否编写了一个静态编译的函数(C / Fortran):你无法编译,因为u_sum的类型是未知的.

2) Why are loops in python so slow?

因为Python中的变量是动态的.每当它命中一个变量时,解释器就需要找出变量是什么,为它找到正确的编译函数,并处理返回的值(可能进行一些转换以隐藏可能发生的真实底层变化).它本质上是一种非类型稳定的Julia函数.

3) Why is the python sum method slower than the numpy.sum method

编写NumPy假设该数组是浮点数的数组. Python数组(列表)通常是任何东西. Julia表示法是Vector {float64} vs Vector {Any}.在第一个中,您可以准确地知道类型是什么,消除类型检查,转换等.您可以知道内存中每种类型的大小是相同的,并且由于它们都是相同的,您可以将它们内联到向量,而不是让内存成为一堆指向真实对象的指针(并且指针间接禁用了许多优化).

4) Why ist the sum function of python geting a slightly different solution than the numpy.sum function?

浮点很奇怪,不是关联的. SciPy中可能存在优化,这会改变某些计算的顺序,可能是某种循环展开

故事的道德启示

通过优化代码变得快速.如果编译器有更多信息,代码可以更好地优化,因为它可以做出更好的假设并删除许多不必要的检查和间接.完全动态的Python可以给解释器/运行时几乎没有信息,迫使它通过最少优化的路径.你可以通过调用用C编写的特定参数类型函数来改善这一点,因为编译器可以优化C代码(这就是SciPy所做的).

Julia旨在允许您为编译器提供静态编译语言的完整信息,但是使用的是大多数动态语言.这是由于类型系统和多次调度.因此,在这些情况下,它能够匹配C / Fortran的编译代码,获得全速,而无需在运行时调用FFI.如果您编写的代码中编译器不能拥有任何信息,例如使输出类型随机,那么编译器就无法进行优化,代码本质上变得动态且速度与Python一样慢.这很好,因为在这些情况下C只会出现段错误…

总结

以上是内存溢出为你收集整理的比较Speed Python3和Julia全部内容,希望文章能够帮你解决比较Speed Python3和Julia所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1195150.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存