不要百度Julia,八成会有惊吓
我说的Julia是这个 - MIT 2012年推出的一门统计学语言。我最开始对这东西不怎么感冒,之前也看过很多现代化语言的语法,包括kotlin、golang、rust和julia。
其中,最喜欢的还是golang和kotlin。rust对我来说太复杂了,试了试就放弃了。
julia给我的感觉也差不多,语法像是几门语言的杂糅。
- C:function和end关键字,写Python和go,甚至是R习惯了,经常漏写end
- Python:主要是类似numpy的矩阵操作
- R:各种基础统计和下标为1。
除此之外,julia的类型系统和.
运算等都会跟人一种这门语言很复杂的感觉。
优点呢,也很明显,在不标明类型的情况下,运行速度都比Python强太多;表明了类型之后速度还能更进一步。另外,pipeline
和PyCall
,RCall
能带来一种在Julia中顺畅的跑bash
,Python
和R
的体验,真的强????,不愧是学院派的语言,一看就就是平常也被各种语言和各种软件的互相调用搞得够恶心。
题外话,说起来现在的静态语言逐步开始发展一些简单的类型推断和泛型。而动态语言开始逐步添加类型系统(Python,Julia都是如此),很有意思的趋势
简单列几个我在julia使用过程中遇到的问题
关于Pkg
Julia自带的包管理器,其正常的用法很多地方都能查到了 ,也没什么好说的
using Pkg
Pkg.add("ArgParse") # 装包
Pkg.precomile() # 我在打包docker的过程中遇到这个问题,如果没有提前precompile,那么在第一次运行julia的时候会自动precompile,经常出问题
问题
-
Pkg
没有竞态保护,也就是说如果同时开了两个julia都在Pkg.add
或者怎么样,那么就会冲突导致包安装编译失败,一旦出现这个问题,目前我没有特别好的解决办法,只有删库重装。 -
Pkg
的包管理,通过generate
可以生成包管理文件,与Pip.lock
,go.mod
以及JS的yarn.lock
等等都是一样的目的。但问题是它似乎只针对module开发,个人脚本就没法通过这个办法去lock运行环境,那其实不利于脚本的 分发。
关于pipeline
我最开始一直卡在如果与pipeline
的stdout
和stderr
交互。官方示例没这玩意,后来偶然间看到的一个示例在恍然大悟
open(pipeline(`cat`), "w", stdin) do w # 这里stdin和stdout都可,具体区别没看过
write(w, "Hello") # 这里println和write都可,具体区别没看过
close(w)
end
open(pipeline(`echo "hello"`), "r", stdout) do r
while !eof(r)
l = readline(r)
println(string("Julia say: ", l))
end
close(r)
end
关于多进程
协程我也没测试过,线程至今1.5.2
版似乎也没出稳定版,所以也没仔细看过
我采用了最显式的写法,结合上关键文档,应该能 解决许多在实际应用过程中的问题
using Distributed
addprocs(4)
@everywhere begin
function test(x::Int64)::Int64
return x * x
end
end
res = pmap(1:10) do p begin
return test(p)
end
# res should be [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
问题
- 进程是通过socks交互传递数据的,每个进程的环境之间相互隔绝,因此,真正用进程的时候会发现在julia一启动就开始把多个进程全开起来,然后一直存活到main结束,即便并不会使用每个子进程,这些进程也会挂在后台。
- 由于每个进程之间环境并不能交互,因此在加载的时候必须通过
@everywhere
表明哪些代码是需要在子进程中加载的,几个不同的方式都可- @everywhere include("run.jl")
- @everywhere begin; # code here; end
RCall和pyCall
- PyCall看文档就行,值的夸赞的是,它是在
precompile
的时候就需要指定好Python的路径,用且只用指定的Python避免了环境的紊乱,点赞(比R的reticulate
强多了,那玩意那叫一个乱) - RCall能够带来julia中写R的原声体验,比Python的
rpy2
强太多了,问题就是有时候可能不太好获取返回值using RCall # 比如,我的解决办法是用collect res = rcopy(R"ksmooth($x, $y, kernel='normal', bandwidth =.5, x.points = $x)") collect(values(res)) # 这就获得了ksmooth的结果,collect之后是一个二维数组,第一个是res$x,第二个是res$y
结束
好了,我把我目前的一些感想都写了一下,希望对想入手Julia的有所帮助吧
有疑问加站长微信联系(非本文作者)