首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Julia is fast

通常,基准测试用于比较语言。这些基准引发长时间的讨论,首先是关于什么是基准测试,其次是解释差异的原因。这些简单的问题有时会比你最初想象的要复杂得多。

概要

定义和函数

总结的实施和基准测试...

C(hand-written)

C(with -ffast-math)

Python(built-in)

Python(numpy)

Python(hand-written)

Julia(built-in)

Julia(hand-written)

Julia(hand-written w.simd)

基准总结

:一个容易理解的功能

考虑计算和的sum函数sum(a)

n

sum()=,

=1

代指的长度

a=rand(10^7)# 产生随机向量

sun(a)

预期结果是0.5 * 10 ^ 7,因为每个条目的平均值是0.5

用几种语言,几种方法进行基准测试

@timesum(a)

宏可以产生嘈杂的结果,因此它不是我们进行基准测试的最佳选择!幸运的是,Julia有一个人BenchmarkTools.jl包,可以轻松准确地进行基准测试:

#using Pkg

#Pkg.add("BenchmarkTools")

usingBenchmarkTools

1.C语言

C通常被认为是黄金标准:对人类很不友好,但对机器而言很友好。 达到C的2倍通常是令人满意的。 尽管如此,即使在C语言中,也有很多种可能的优化,一个C作者可能会或又可能不会去优化。

很高兴地告诉你可以将C代码放入Julia会话,编译并运行它。 请注意,”“”多行字符串。

usingLibdl

C_code="""

#include

double c_sum(size_t n, double *X) {

double s = 0.0;

for (size_t i = 0; i

s += X[i];

}

return s;

}

"""

constClib=tempname()# make a temporary file

# compile to a shared library by piping C_code to gcc

# (works only if you have gcc installed):

open(`gcc -fPIC -O3 -msse3 -xc -shared -o $(Clib * "." * Libdl.dlext) -`,"w")dof

print(f,C_code)

end

# define a Julia function that calls the C function:

c_sum(X::Array)=ccall(("c_sum",Clib),Float64, (Csize_t,Ptr{Float64}),length(X),X)

isapprox

我们现在可以直接从Julia对C代码进行基准测试:

d=Dict()#a"dictionary",i.e.anassociativearray

d["C"]=minimum(c_bench.times)/1e6#inmilliseconds

d

using Plots

gr()

using Statistics # bring in statistical support for standard deviations

t = c_bench.times / 1e6 # times in milliseconds

m, σ = minimum(t), std(t)

histogram(t, bins=500,

xlim=(m - 0.01, m + σ),

xlabel="milliseconds", ylabel="count", label="")

2.C with -ffast-math

如果我们允许C重 新安排浮点运算,那么他将使用SIMD(单指令,多数据)指令进行向量化

const Clib_fastmath = tempname() # make a temporary file

# The same as above but with a -ffast-math flag added

open(`gcc -fPIC -O3 -msse3 -xc -shared -ffast-math -o $(Clib_fastmath * "." * Libdl.dlext) -`, "w") do f

print(f, C_code)

end

# define a Julia function that calls the C function:

c_sum_fastmath(X::Array) = ccall(("c_sum", Clib_fastmath), Float64, (Csize_t, Ptr), length(X), X)

3.Python's built in sum

PyCall包为Python提供了Julia接口:

# using Pkg;Pkg.add("PyCall")

using PyCall

# get the Python built-in "sum" function

pysum=pybuiltin("sum")

pysum(a)

pysum(a)≈sum(a)

py_list_bench=@benchmark$pysum($a)

d["Python built-in"]=minimum(py_list_bnech.times)/1e6

print(d)

4.Python:numpy

利用硬件“SIMD”,但只在它工作是才有效。numpy是一个优秀的C库,可以从Python调用。它可以安装在 Julia中,如下所示

# using Pkg;Pkg.add("Conda")

usingConda

# Conda.add("numpy")

numpy_sum=pyimport("numpy")["sum"]

py_numpy_bench=@benchmark$numpy_sum($a)

numpy_sum(a)

numpy_sum(a)≈sum(a)

d["Python numpy"]=minimum(py_numpy_bench.times)/1e6

print(d)

5.Python,hand-written

py"""

def py_sum(A):

s=0.0

for a in A:

s += a

return s

"""

sum_py=py"py_sum"

py_hand=@benchmark$sum_py($a)

sum_py(a)

sum_py(a)≈sum(a)

d["Python hand-written"] =minimum(py_hand.times)/1e6

print(d)

6.Julia (built-in)

在Julia中书写 ,不是在C中

@whichsum(a)

j_bench=@benchmarksum($a)

d["Julia built-in"]=minimum(j_bench.times)/1e6

print(d)

7.Julia (hand-written)

functionmysum(A)

s=0.0#s = zero(eltype(a))

forainA

s+=a

end

s

end

j_bench_hand=@benchmarkmysum($a)

d["Julia hand-written"]=minimum(j_bench_hand.times)/1e6

print(d)

8.Julia(hand-written w.simd)

functionmysum_simd(A)

s=0.0#s = zero(elype(A))

@simdforainA

s+=a

end

s

end

j_bench_hand_simd=@benchmarkmysum_simd($a)

mysum_simd(a)

d["Julia hand-written simd"]=minimum(j_bench_hand_simd.times)/1e6

print(d)

9. Summary

for(key,value)in sort(collect(d),by=last)

println(rpad(key,25,"."),lpad(round(value;digits=1),6,"."))

end

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190121G0O7SJ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券