引言:为什么还要再学一门语言
做数据分析的人通常已经身在 R 或 Python 的生态里,再学一门语言似乎并不划算。Julia 之所以值得一试,是因为它瞄准的是一个长期痛点——“两语言问题”(two-language problem):用易写的动态语言(R / Python)做原型,一旦性能不够,就得用 C / C++ / Fortran 重写热点,于是同一套逻辑要维护两份。
Julia 的目标是让同一份代码既好写又快。它是一门动态类型语言,却通过 JIT(即时编译) 和 多重派发(multiple dispatch) 把性能推到了接近静态编译语言的量级。对科学计算而言,它的几个特点尤其对胃口:
- 为数值而生:原生支持多维数组、线性代数、复数、有理数,语法贴近数学公式;
- 快:类型稳定的代码性能可与 C 媲美,且无需离开这门语言;
- 多重派发:函数行为由所有参数的类型共同决定,这是它最核心的设计;
- 生态互通:
JuliaCall/RCall.jl/PythonCall.jl让 Julia 可以和 R、Python 互相调用。
官方社区:https://julialang.org/;中文社区:https://cn.julialang.org/。
中文入门参考:https://www.math.pku.edu.cn/teachers/lidf/docs/Julia/html/_book/basics.html
安装 Julia
推荐方式:juliaup
现在官方推荐用 juliaup(Julia 官方版本管理器)安装,它同时解决了"装哪个版本"和"如何切换版本"两个问题。
macOS / Linux:
|
|
Windows(PowerShell 或 CMD):
|
|
安装完成后重启终端,或手动加载 shell 配置:
|
|
早期方式:jill
juliaup 出现之前,社区常用 Python 写的 jill 来安装(即本篇最初记录的方法)。它现在仍然可用,但新用户没必要再用:
|
|
其中 --upstream BFSU 指定从北京外国语大学镜像下载,在校园网 / 国内网络下速度明显更快。
验证与版本管理
|
|
juliaup 常用命令:
| 命令 | 作用 |
|---|---|
juliaup list |
列出所有可用 channel(release / lts / 1.10 等) |
juliaup add 1.10 |
额外安装 1.10 系列 |
juliaup default lts |
把默认版本切到长期支持版 |
juliaup update |
更新所有已安装版本 |
juliaup remove 1.10 |
卸载某个版本 |
julia +1.10 |
临时用某个版本启动 |
进入 REPL
直接在终端输入 julia 即可进入交互式环境(REPL,即 Read-Eval-Print Loop):
|
|
REPL 有几个模式,这是 Julia 的鲜明特色:
julia>:默认模式,执行代码;- 按
]进入 Pkg 模式,提示符变为(@v1.12) pkg>,用于装包、管理环境; - 按
;进入 shell 模式,可直接执行系统命令; - 按
?进入 help 模式,输入任意函数名即可查看文档; - 按
Backspace退回默认模式,Ctrl-D或exit()退出。
小技巧:REPL 输入被自动补全(Tab),
ans变量保存上一次的结果,行尾加;则不打印返回值。
基本语法速览
Julia 的语法对 R / Python 用户来说相当亲切。下面给出常用片段,配合 REPL 逐个敲一遍即可建立手感。
变量与类型
Julia 是动态类型语言,变量无需声明类型,但每个值都有具体类型:
|
|
数值字面量支持数学写法,比如 2im(复数)、3//4(有理数)、1e-3(科学计数)。
字符串
|
|
数组与广播
数组是 Julia 的主角。注意两个和 R 不同的地方:索引从 1 开始,列优先(column-major)存储。
|
|
点号 . 是**广播(broadcasting)**运算符,表示"逐元素"操作。这是 Julia 里极高频率出现的语法。
控制流与循环
|
|
函数
|
|
核心特性:多重派发
多重派发是 Julia 区别于其他语言的关键设计。同一个函数名可以有一组方法(method),Julia 会根据所有实参的类型在运行时选择最匹配的那个:
|
|
在 REPL 里用 methods(f) 可以列出某个函数的所有方法。这与 R 的 S3/S4 泛型函数、Python 的单派发有相似之处,但 Julia 让多个参数共同参与选择——例如 *(::Matrix, ::Vector) 与 *(::Vector, ::Matrix) 可以是完全不同的实现。
围绕类型系统,还会用到:
|
|
struct 定义复合类型,<: 表示子类型关系。抽象类型 + 具体类型 + 多重派发的组合,是 Julia 组织大型代码库的基本范式。
包管理:Pkg
Julia 内置了包管理器 Pkg,无需额外安装。在 REPL 中按 ] 进入 Pkg 模式后:
|
|
等价的脚本写法:
|
|
环境(Project)
Julia 用环境隔离不同项目的依赖,核心是两个文件:Project.toml(直接依赖)和 Manifest.toml(完整依赖图,含精确版本)。为项目创建独立环境:
|
|
之后启动一个使用该环境的会话:
|
|
实践建议:每个项目一个环境,把
Project.toml和Manifest.toml都提交到 Git,这样环境可精确复现。这一点和 R 的renv、Python 的虚拟环境思路一致。
常用生态包:
| 领域 | 包 |
|---|---|
| 数据结构 | DataFrames.jl、DataFramesMeta.jl |
| 绘图 | Plots.jl(易用)、Makie.jl(高性能) |
| 统计 / 贝叶斯 | Statistics(标准库)、Distributions.jl、Turing.jl |
| 微分方程 | DifferentialEquations.jl |
| 机器学习 | MLJ.jl、Flux.jl |
| R / Python 互调 | RCall.jl、PythonCall.jl |
性能:为什么 Julia 快
Julia 的快来自 JIT 编译 + 类型稳定(type stability)。所谓类型稳定,是指函数内部变量的类型可以从输入类型推断出来。类型稳定的代码,编译器能生成接近 C 的机器码。
|
|
几个诊断工具:
@time:查看耗时与内存分配(注意首次调用包含编译时间,测性能要跑第二次);@btime/@benchmark:来自BenchmarkTools.jl,多次运行取统计量;@code_warntype:高亮类型不稳定的位置,帮助定位性能瓶颈。
另一个易踩的坑是全局变量:在脚本顶层定义的全局变量会让编译器难以做类型推断,从而明显变慢。标准做法是把逻辑写进函数,或把全局变量声明为 const。
与 R / Python 的互操作
Julia 并不要求你把现有代码全部重写。以 R 为例,两个方向都有成熟的桥:
在 R 里调用 Julia——用 JuliaCall:
|
|
在 Julia 里调用 R——用 RCall.jl:
|
|
同理,PythonCall.jl / PyCall.jl 让 Julia 可以直接使用 Python 生态。这意味着可以只把性能热点用 Julia 重写,其余部分留在 R / Python——正是对"两语言问题"的务实解。
优缺点
优点
- 快:类型稳定的代码性能接近 C,无需为了性能换语言;
- 数值友好:语法贴近数学,原生支持数组、线性代数、复数等;
- 多重派发:表达力强,代码组织清晰,适合构建大型科学计算库;
- 包管理器内置且可复现:环境(Project / Manifest)开箱即用;
- 互操作性好:可与 R、Python、C 相互调用,渐进式采用。
局限
- 首次调用慢:JIT 编译导致第一次运行有"编译延迟"(time-to-first-plot 是常见吐槽);
- 生态相对年轻:包的数量和成熟度不及 R / Python,某些细分领域可能缺库;
- 全局变量陷阱:不写成函数就容易踩性能坑,对新手不友好;
- 内存占用:运行时与编译缓存会占用较多内存与磁盘;
- 调试体验:错误栈信息偶尔偏底层,需要时间适应。
注意事项
- 测性能要跑第二次:首次调用包含编译时间,别被吓到;
- 把逻辑写进函数:避免顶层全局变量拖慢执行;
- 固定环境:提交
Project.toml和Manifest.toml,保证可复现; - 别急着全部重写:先用
JuliaCall/RCall.jl做增量替换,性价比更高。
学习资源
- 官方文档:https://docs.julialang.org/
- 官方学习页:https://julialang.org/learning/
- 中文社区:https://cn.julialang.org/
- 北大李东风《Julia 语言入门》:https://www.math.pku.edu.cn/teachers/lidf/docs/Julia/html/_book/basics.html
- Modern Julia Workflows(工作流实践):https://modernjuliaworkflows.org/
- 与 R / Python 的差异速查:官方手册 Noteworthy Differences from other Languages 一节值得先读。
小结
Julia 用 JIT + 多重派发 + 类型系统,试图在"好写"和"快"之间不再二选一。本文走通了从安装(juliaup)、REPL 模式、基本语法、多重派发、Pkg 环境管理,到性能诊断与 R 互操作的入门路径。对已有 R / Python 工作流的科研人员,最省力的入手方式是:先把它当作可被 R 调用的"高性能计算后端"(JuliaCall),在真实问题里逐步体会它的设计取舍。