news 2026/3/4 11:12:08

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

作者头像

张小明

前端开发工程师

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/2/28 7:26:09

PyTorch-CUDA-v2.8镜像对Llama模型的本地运行支持

PyTorch-CUDA-v2.8镜像对Llama模型的本地运行支持 在AI开发者圈子里&#xff0c;一个常见的场景是&#xff1a;你兴致勃勃地准备跑通Llama-3-8B的推理代码&#xff0c;结果卡在了环境配置——CUDA版本不匹配、PyTorch报错、torch.cuda.is_available() 返回 False……几小时过去…

作者头像 李华
网站建设 2026/2/27 15:41:43

PyTorch-CUDA镜像对量化感知训练的支持情况

PyTorch-CUDA镜像对量化感知训练的支持情况 在当前AI模型日益庞大的背景下&#xff0c;如何在不显著牺牲精度的前提下压缩模型、提升推理效率&#xff0c;已成为工业界和学术界的共同挑战。随着ResNet、BERT等大型模型的广泛应用&#xff0c;动辄数百MB甚至GB级的参数量让它们难…

作者头像 李华
网站建设 2026/2/28 7:32:33

Playwright 并行测试:配置与优化技巧

当你需要运行大量测试用例时&#xff0c;串行执行会消耗大量时间。想象一下&#xff0c;500个测试用例每个耗时1分钟&#xff0c;串行执行需要8个多小时——这在实际开发中是不可接受的。Playwright的并行测试能力可以将这个时间缩短到几分钟&#xff0c;大幅提升开发和交付效率…

作者头像 李华
网站建设 2026/2/25 15:59:02

PyTorch-CUDA镜像支持中文路径吗?编码问题详解

PyTorch-CUDA 镜像支持中文路径吗&#xff1f;编码问题详解 在深度学习项目开发中&#xff0c;我们常常会遇到一个看似简单却令人头疼的问题&#xff1a;为什么我的代码在本地运行得好好的&#xff0c;一放到容器里就报“文件不存在”&#xff1f;尤其是当路径里包含“张伟的实…

作者头像 李华
网站建设 2026/3/3 9:56:55

ViGEmBus虚拟游戏手柄驱动:让所有手柄在PC上畅玩游戏的终极指南

ViGEmBus虚拟游戏手柄驱动&#xff1a;让所有手柄在PC上畅玩游戏的终极指南 【免费下载链接】ViGEmBus 项目地址: https://gitcode.com/gh_mirrors/vig/ViGEmBus 你是否曾经遇到过这样的困扰&#xff1a;心爱的手柄连接电脑后&#xff0c;游戏却完全无法识别&#xff1…

作者头像 李华