news 2026/5/20 18:28:44

基于莱布尼茨公式的编程语言计算性能基准测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于莱布尼茨公式的编程语言计算性能基准测试

利用莱布尼茨公式(Leibniz formula)计算圆周率 $\pi$。尽管在现代数学计算库中,莱布尼茨级数因其收敛速度极慢而鲜被用于实际精算 Π 值,但其算法结构——高密度的浮点运算、紧凑的循环逻辑以及对算术逻辑单元(ALU)的持续压力——使其成为测试 CPU 单核吞吐量、浮点运算单元(FPU)效率以及编译器自动向量化(Auto-vectorization)能力的绝佳“试金石” 。

GitHub 开源项目 niklas-heer/speed-comparison 在 2025 年 12 月产生的最新数据,涵盖了从底层系统级语言(如 C++、Rust)到托管型语言(如 Java、C#),再到动态解释型语言(如 Python、Ruby)的 62 种不同实现。通过对 10 亿次迭代运算的详尽分析,我们不仅试图排列出“谁最快”,更致力于揭示“为什么快”背后的深层技术逻辑,探讨单指令多数据(SIMD)技术、即时编译(JIT)机制以及内存模型对计算性能的决定性影响。

上图来自:https://niklas-heer.github.io/speed-comparison/

莱布尼茨公式,作为 arctan(x) 的泰勒级数在 x=1时的特例,其数学表达为:

从算法实现的角度审视,该公式具有以下显著特征,这些特征直接决定了其作为基准测试的有效性:

  1. 极端的计算密集度:算法核心仅包含基本的加、减、乘、除运算,几乎不涉及复杂的内存分配或系统调用(System Calls)。这使得测试结果能够高度纯粹地反映语言运行时的计算开销和指令生成质量 。

  2. 可预测的分支逻辑:公式中的符号交替项 (-1)^k 引入了潜在的分支预测(Branch Prediction)挑战。朴素的实现可能会在循环内部使用if (i % 2 == 0)

判断奇偶性,这将导致大量的 CPU 分支预测失败,从而严重拖慢流水线。而高效的实现通常采用无分支(Branchless)技巧,利用位运算或数学变换来消除条件跳转,这考验了程序员对底层硬件的理解以及编译器的优化智能 。

  • 浮点精度与收敛性:虽然本基准测试明确声明“不关注 pi的精确度”,仅关注运算速度,但浮点数(IEEE 754 标准)的累加特性使得计算顺序对结果有微小影响。编译器是否开启-ffast-math等激进优化选项(允许改变浮点结合律)对性能有着数量级的影响,这成为了不同语言实现之间性能差异的主要变量之一 。

  • 基于 2025 年 12 月的最新基准测试数据,我们将 62 种语言实现划分为四个具有显著特征的性能梯队。

    第一梯队:极限性能层 (< 300ms) —— 编译器的极致

    这一梯队的语言代表了当前通用 CPU 单核计算的物理极限。它们几乎完全消除了语言本身的运行时开销,性能瓶颈仅在于 CPU 的 ALU 吞吐量和内存带宽。

    深度剖析:

    第二梯队:亚秒级高性能层 (300ms - 1000ms) —— 标量优化的极限

    这一梯队的语言性能非常出色,通常在 0.5 秒到 1 秒之间。它们大多生成了高效的机器码,但因未开启激进的 SIMD 优化或受到运行时轻微拖累,未能进入第一梯队。

    深度剖析:

    第三梯队:解释与混合层 (1s - 5s) —— JIT 的战场

    这一梯队主要包含动态类型语言的高性能 JIT 实现,或启动开销较大的静态语言环境。

    深度剖析:

    第四梯队:纯解释器层 (> 10s) —— 动态类型的代价

    最慢的梯队,主要是未优化的脚本语言解释器。

    深度剖析:

    C#:.NET Core 的高性能复兴

    在本次测试中,C# (SIMD) 的表现(227ms)是最令人瞩目的亮点之一。这主要归功于.NET Core(现称为.NET 5/6/7+)引入的硬件内建支持(Hardware Intrinsics)。

    • 实现细节:通过引用System.Runtime.Intrinsics或使用更高级的System.Numerics.Vector<T>,C# 开发者可以编写出直接映射到 CPU 向量指令的代码。

    • JIT 的优势:与 C++ 的 AOT(提前编译)不同,C# 的 JIT 编译器在程序运行时知道当前 CPU 确切支持哪些指令集(是 AVX2 还是 AVX-512)。这使得 C# 程序可以在旧机器上安全运行,而在新机器上自动全速狂奔,无需像 C++ 那样发布多个二进制版本。基准测试结果证明,这种机制在数值计算领域已经完全成熟 。

    • CPython 的性能瓶颈:标准 Python(CPython)以 86.32 秒垫底,比 C++ 慢了近 400 倍。这归因于其虚拟机架构:每一次加法操作都需要进行对象类型检查(Type Checking)、引用计数更新(Reference Counting)和字节码分发(Dispatch)。对于 10 亿次循环,这些微小的开销累积成了巨大的时间鸿沟 。

    • 解释器的局限:这一梯队的语言(PHP, Ruby, Perl, Raku)在处理紧凑循环时,CPU 主要忙于解释器自身的逻辑(解析字节码、管理栈),而非执行实际的数学运算。

    • PyPy 的惊艳表现:PyPy 将 Python 的运行时间压缩至 1.06 秒,仅比 C# 标准版慢一点。这得益于其 Tracing JIT 技术,能够动态记录循环的执行路径并编译为机器码,消除了动态类型检查的巨大开销 。

    • NumPy 的陷阱:虽然 NumPy 底层是 C,但在此测试中(2.46s)表现平平。这是因为测试代码使用了 Python 层的for循环逐个调用 NumPy 的标量运算。NumPy 的威力在于数组操作(Vectorization),在标量调用场景下,Python 与 C 之间的上下文切换(Function Call Overhead)反而成为了负担。若允许重写为数组操作,NumPy 可能会进入第一梯队,但这违反了“算法一致性”规则 。

    • Java 的启动与优化:标准 Java (1.70s) 表现中规中矩。HotSpot 编译器虽然强大,但在无法自动向量化浮点循环的情况下,受限于 JVM 的栈操作开销。此外,Java 巨大的启动时间(JVM 初始化、类加载)在短时任务中占比显著。

    • Rust 的版本鸿沟:Rust (Stable) 耗时 633ms,而 Nightly 版仅需 234ms。这种巨大的差距源于 Rust 稳定版对 IEEE 754 浮点行为的严格遵守,阻止了编译器进行改变运算顺序的向量化优化。只有在 Nightly 版中显式启用相关特性,才能释放硬件潜力 。

    • Go 的妥协:Go 语言(888ms)稳定地处于这一梯队。Go 的编译器(gc)设计初衷是编译速度快,而非生成的代码最快。它在自动向量化方面远不如 LLVM 激进,且 Go 运行时包含的调度器和垃圾回收(GC)屏障(Write Barriers)在微观层面引入了额外开销 。

    • JavaScript 的运行时之战:Bun (928ms) 显著快于 Node.js (1.28s)。Bun 使用的 JavaScriptCore (JSC) 引擎在特定数值计算优化上表现出了相比 Google V8 的优势,证明了现代 JS 引擎的 JIT 能力已能逼近原生代码(仅慢 3-4 倍)。

    • LLVM 的霸权:前 10 名中,C++ (Clang)、Zig、D (LDC)、Rust (Nightly) 均依赖 LLVM 编译器后端。这证明了 LLVM 在现代处理器指令调度和向量化分析上的卓越能力。

    • C# 的惊人逆袭:C# (SIMD) 位列第二,仅落后 C++ 不到 4 毫秒。这打破了“托管语言一定慢”的刻板印象。通过.NET 的System.Numerics.Vectors库,C# 能够生成与 C++ 几乎相同的 AVX-512 机器码,同时享受 JIT 针对当前硬件动态优化的优势 。

    • 手写 vs 自动:排名第 4 的 C++ (avx2) 是手写 SIMD 代码,却输给了编译器自动优化的 Clang (第 1)。这说明在简单的循环逻辑中,现代编译器对流水线气泡(Pipeline Bubble)和寄存器分配的掌控已经超越了普通人类专家 。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 20:44:44

PyTorch镜像中运行FastAPI暴露模型接口

PyTorch镜像中运行FastAPI暴露模型接口 在AI模型从实验室走向生产环境的今天&#xff0c;一个常见的挑战是&#xff1a;如何让训练好的深度学习模型真正“跑起来”&#xff0c;并稳定地为前端应用、移动端或业务系统提供服务&#xff1f;很多算法工程师能写出优秀的模型代码&am…

作者头像 李华
网站建设 2026/5/20 18:28:38

三极管工作原理及详解:动态响应仿真分析

三极管工作原理详解&#xff1a;从载流子运动到动态响应仿真你有没有遇到过这样的情况&#xff1f;电路板上的三极管明明“导通”了&#xff0c;输出却迟迟不上升&#xff1b;或者音频放大器一放大就失真&#xff0c;调了半天偏置也没用。问题可能不在于你算错了静态工作点&…

作者头像 李华
网站建设 2026/5/20 18:28:45

用VHDL完成抢答器设计:课程大作业FPGA应用实例

从零实现一个FPGA抢答器&#xff1a;VHDL课程设计实战全记录最近带学生做《EDA技术》课设&#xff0c;又轮到“抢答器”这个经典项目登场了。别看它功能简单——四个按钮、谁先按亮灯显示编号&#xff0c;背后却藏着数字系统设计的核心逻辑&#xff1a;时序控制、状态管理、硬件…

作者头像 李华
网站建设 2026/5/20 18:28:48

arm64轻量高效,x64性能强劲?快速理解关键点

arm64轻量高效&#xff0c;x64性能强劲&#xff1f;别被标签骗了&#xff0c;真正区别在这你有没有遇到过这样的争论&#xff1a;“arm64是手机芯片&#xff0c;只能省电&#xff0c;跑不动大程序。”“x64才是真生产力&#xff0c;打游戏、做渲染还得靠Intel和AMD。”这些说法…

作者头像 李华
网站建设 2026/5/20 18:28:46

PyTorch-CUDA-v2.8镜像网络配置说明:代理与外网访问

PyTorch-CUDA-v2.8镜像网络配置说明&#xff1a;代理与外网访问 在企业级AI开发环境中&#xff0c;一个常见的挑战是&#xff1a;如何在严格网络管控的内网中&#xff0c;顺利运行需要频繁访问外部资源&#xff08;如PyPI、GitHub、模型仓库&#xff09;的深度学习任务&#xf…

作者头像 李华
网站建设 2026/5/20 18:28:45

PyTorch-CUDA镜像适合新手吗?三大优势告诉你答案

PyTorch-CUDA镜像适合新手吗&#xff1f;三大优势告诉你答案 在深度学习的世界里&#xff0c;很多初学者的第一道坎不是写不出模型&#xff0c;而是——环境装不上。 你兴致勃勃地打开教程&#xff1a;“今天我要训练第一个神经网络&#xff01;” 结果刚执行 import torch 就报…

作者头像 李华