美文网首页
2020-10-28 最近折腾了一下Julia

2020-10-28 最近折腾了一下Julia

作者: zhym1992 | 来源:发表于2020-10-28 11:45 被阅读0次

    不要百度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强太多;表明了类型之后速度还能更进一步。另外,pipelinePyCallRCall能带来一种在Julia中顺畅的跑bashPythonR的体验,真的强👍,不愧是学院派的语言,一看就就是平常也被各种语言和各种软件的互相调用搞得够恶心。

    题外话,说起来现在的静态语言逐步开始发展一些简单的类型推断和泛型。而动态语言开始逐步添加类型系统(Python,Julia都是如此),很有意思的趋势

    简单列几个我在julia使用过程中遇到的问题

    关于Pkg

    Julia自带的包管理器,其正常的用法很多地方都能查到了 ,也没什么好说的

    using Pkg
    Pkg.add("ArgParse")   # 装包
    Pkg.precomile()  # 我在打包docker的过程中遇到这个问题,如果没有提前precompile,那么在第一次运行julia的时候会自动precompile,经常出问题
    

    问题

    1. Pkg没有竞态保护,也就是说如果同时开了两个julia都在Pkg.add或者怎么样,那么就会冲突导致包安装编译失败,一旦出现这个问题,目前我没有特别好的解决办法,只有删库重装。
    2. Pkg的包管理,通过generate可以生成包管理文件,与Pip.lockgo.mod以及JS的yarn.lock等等都是一样的目的。但问题是它似乎只针对module开发,个人脚本就没法通过这个办法去lock运行环境,那其实不利于脚本的 分发。

    关于pipeline

    我最开始一直卡在如果与pipelinestdoutstderr交互。官方示例没这玩意,后来偶然间看到的一个示例在恍然大悟

    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]
    

    问题

    1. 进程是通过socks交互传递数据的,每个进程的环境之间相互隔绝,因此,真正用进程的时候会发现在julia一启动就开始把多个进程全开起来,然后一直存活到main结束,即便并不会使用每个子进程,这些进程也会挂在后台。
    2. 由于每个进程之间环境并不能交互,因此在加载的时候必须通过@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的有所帮助吧

    相关文章

      网友评论

          本文标题:2020-10-28 最近折腾了一下Julia

          本文链接:https://www.haomeiwen.com/subject/tlsqvktx.html