Neanderthal 为什么声称比普通 Clojure/Java 库快很多?
更新时间
Neanderthal 的速度声明建立在“把数值计算交给原生 BLAS/LAPACK 或 GPU 引擎,Clojure 只保留一层薄接口”这一架构上。按官网给出的数字,它在 GPU 上处理大矩阵时比优化过的 Clojure/Java 库快近 3000 倍,在 CPU 上比优化过的纯 Java 实现快 100 倍。这些倍数有明确前提:比较对象是“优化过的”Java/Clojure 数值库,且大矩阵、GPU 场景对应的是前一个数字。若你的矩阵很小、数据在 JVM 堆内频繁转换,或没有可用的 GPU/原生 BLAS 环境,实际收益会明显缩小,需要以自己的负载做基准测试。
速度来自哪里
计算下沉到原生 BLAS/LAPACK 与 GPU
Neanderthal 不重新实现矩阵乘法和分解算法,而是把数值计算部分交给原生 BLAS 和/或 GPU 完成,自己只提供一层很小的 Clojure 封装。官网的说法是“不拙劣地重新发明轮子”,并强调尊重 BLAS/LAPACK 数十年的标准化。这意味着它复用的是经过长期优化的底层内核,而不是 JVM 上逐元素循环的纯 Java 实现。
GPU 引擎支持 AMD、Nvidia、Intel 硬件,也支持 Mac OSX;LAPACK 支持已覆盖分解与求解器。官网称 GPU 上大矩阵可比优化过的 Clojure/Java 库快近 3000 倍,CPU 上比优化过的纯 Java 快 100 倍。
为 Clojure 设计的原始类型 map/reduce
除了底层内核,Neanderthal 还提供快速的原始类型(primitive)版本的 map 和 reduce。普通 Clojure 的序列抽象在数值密集循环中会带来装箱和序列开销,原始类型版本减少了这层开销,使函数式写法在数值计算路径上更可用。
可插拔引擎,按性能需求取舍
引擎实现是可插拔的,官网明确说“甚至可以把纯 Java 引擎插进来,用于速度不是优先级的场景”。这解释了一个关键机制:快不是库的固定属性,而是所选引擎的属性。选择原生/GPU 引擎获得性能,选择纯 Java 引擎获得可移植性或部署简单性。
一个具体例子
假设你要在 Clojure 中做一次大规模矩阵乘法。用普通 Clojure/Java 库,计算通常发生在 JVM 内,逐元素或分块循环由 Java 代码执行;用 Neanderthal 并选用 GPU 引擎,同样的乘法被下推到 GPU 上的 BLAS 内核执行,Clojure 侧只负责组织输入和取回结果。官网给出的“近 3000 倍”对应的正是这类大矩阵、GPU 可用的场景。反过来,如果矩阵规模很小,内核启动和数据传输的固定成本占比上升,倍数就失去参考意义。
这些数字怎么用
| 你的条件 | 可预期的收益 | 依据 |
|---|---|---|
| 大矩阵 + 可用 GPU(AMD/Nvidia/Intel/Mac OSX) | 官网称相对优化 Clojure/Java 库近 3000 倍 | 官网 GPU 声明 |
| CPU 上的原生 BLAS 路径 | 官网称相对优化纯 Java 快 100 倍 | 官网 CPU 声明 |
| 小矩阵或频繁 JVM 与原生间数据搬运 | 倍数不适用,需自行基准测试 | 声明前提是“大矩阵” |
| 速度不是优先级、需要纯 JVM 部署 | 可插拔纯 Java 引擎,放弃上述加速 | 官网引擎可插拔说明 |
判断是否值得采用,最稳妥的方式是拿你自己的矩阵规模和硬件,对照官网的 benchmarks 页面跑一遍,而不是直接套用宣传倍数。官网提供了 Get Started、Benchmarks、API docs 和教程入口,代码与理论部分也以 BLAS/LAPACK 为中心,现有数值线性代数资料可以继续沿用。
需要注意的边界
官网页面没有给出具体版本号、支持矩阵类型清单或各引擎的安装步骤,这些需要查 API docs 和教程。价格方面,页面出现“subscription”字样,指的是新书可订阅,以及通过 Patreon 支持作者、获得 Discord 讨论邀请(付不起也可申请免费邀请);这并不等于库本身的使用条款,采用前应自行确认许可与部署要求。