当前位置:首页>python>多语言性能终极角斗场:从 ASM 到 Python 的全方位评测 (2026年)

多语言性能终极角斗场:从 ASM 到 Python 的全方位评测 (2026年)

  • 2026-01-28 03:12:54
多语言性能终极角斗场:从 ASM 到 Python 的全方位评测 (2026年)

1. 前言

1.1 永恒的战争

在软件开发的世界里,关于编程语言性能的争论从未停止。是选择“贴地飞行”的 C/Assembly 以榨干 CPU 的每一个周期,还是拥抱 Python/JavaScript 的开发效率而牺牲部分运行时速度?或者,选择 Rust、Go、.NET 10 这样的现代中间路线?

时间来到 2026 年,编译器技术(如 GCC 15 和 Rust 1.92)已经进化到了新的高度,解释型语言的 JIT 优化也愈发激进。旧的刻板印象是否依然成立?Java 25 的启动速度是否不再是短板?Python 3.14 是否在无 GIL 的道路上彻底起飞?

1.2 参战选手

本次评测我们将目光投向以下十位选手,涵盖了从底层指令到高层脚本的完整光谱:

  • • 绝对底层ASM (NASM) —— 机器码的直接翻译者。
  • • 系统级霸主C (GCC)C++ (G++)Rust —— 零抽象成本的追求者。
  • • 现代云原生Go —— 简洁与并发的平衡。
  • • 工业级托管运行时Java (OpenJDK)C# (.NET 10) —— 强大的 JIT 与生态系统。
  • • 动态脚本语言JavaScript (Node.js)PythonPHP —— 灵活性与开发速度的代表。

1.3 评测核心:拒绝 "time ./script"

我们拒绝使用简单的 time 命令进行粗糙计时。为了保证数据的科学性与可复现性,本次测试统一采用 Hyperfine 作为基准测试工具。它提供了自动预热(Warmup)、统计异常值剔除以及更精确的置信区间分析,确保我们看到的不是偶然的抖动,而是真实的性能差距。


2. 测试环境与方法论

为了确保测试结果的公正性,必须详细披露软硬件环境。本次测试是在一台配备了 AMD Zen 4 架构处理器的 Ubuntu 24.04 lts 环境下进行。

2.1 硬件配置 (Hardware)

值得注意的是,测试环境配备了高性能的 CPU,但内存相对紧凑(约 4GB),这将考验各语言运行时(Runtime)在内存受限场景下的 GC 效率与开销。

  • • CPU: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics (Zen 4 架构)
  • • RAM: 3.8 GiB (系统总安装内存)
  • • OS Kernel: Linux 6.19.0-rc5-custom-2026.0112.00

2.2 编译器与运行时版本 (Software)

所有测试工具链均更新至 2026 年 1 月的最新稳定版。

语言
编译器/运行时
版本信息
备注
C
GCC
15.2.0
-O3
 优化
C++
G++
15.2.0
-O3 -std=c++17
ASM
NASM
3.01
elf64
 格式
Rust
Rustc
1.92.0
--release
 模式
Go
Go
1.25.5
go build -ldflags "-s -w"
Java
OpenJDK
25.0.1
启用最新 JIT 优化
C#
.NET SDK
10.0.101
Release 模式, AOT (视场景定)
Node.js
Node
v25.3.0
启用 V8 优化
Python
CPython
3.14.2
标准解释器
PHP
PHP CLI
8.5.1
开启 Opcache (CLI模式)

2.3 构建与优化策略

所有编译型语言(C, C++, Rust, Go, ASM, C#)均使用 Release/Production 模式进行构建。

  • • C/C++: 使用 -O3 开启最高级别优化。
  • • Rust: 使用 --release (opt-level=3)。
  • • Go: 去除调试符号 (-s -w) 以减小体积,虽不直接影响速度,但符合生产环境部署习惯。
  • • .NET 10: 使用 dotnet publish -c Release 生成独立可执行文件。

2.4 测试流程 (Benchmark Methodology)

测试流程由 Makefile 自动化编排,具体执行逻辑如下:

  1. 1. 预热 (Warmup):对于带有 JIT(即时编译)的语言(Java, C#, Node.js, PHP, Python),冷启动性能往往较差。为了测试其“峰值吞吐量”,我们在 Hyperfine 中设置了 3 次预热运行 (--warmup 3),让 JIT 有机会将热点代码编译为机器码。注:在“场景五:冷启动”测试中,将关闭预热功能。
  2. 2. 运行次数:每个场景至少运行 10 次 (--min-runs 10)。如果单次运行时间极短(小于 0.2秒),Hyperfine 会自动增加运行次数以获取足够的样本量。
  3. 3. 环境隔离:由于测试机内存为 3.8GiB,我们在运行大内存占用场景(如 Java/C# 的复杂对象创建)前,会确保系统无其他重负载任务,防止 Swap 交换对 I/O 造成干扰。
  4. 4. 指令示例:
    hyperfine --warmup 3 --min-runs 10 \    --export-markdown results/scene1.md \    -n "C (GCC 15)" "./bin/scene1_primes_c" \    -n "Python 3.14" "python3 scene1/primes.py"

接下来,我们将进入第一个战场:纯 CPU 密集型运算,看看在最纯粹的数学计算面前,谁才是真正的王者。


3. 场景一:纯 CPU 密集型运算 —— 质数筛选 (Sieve of Eratosthenes)

3.1 战场法则

如果说编程语言是武器,那么“质数筛选”就是最纯粹的打靶训练。

本场景采用经典的 埃拉托色尼筛法 (Sieve of Eratosthenes),计算 10,000,000 (一千万) 以内的素数个数。这个算法的特点是极其密集的内存写入操作(标记非素数)和频繁的 CPU 分支预测。它不涉及任何 I/O,也不涉及复杂的对象创建,它只考验两件事:

  1. 1. CPU 指令执行效率:循环展开、流水线优化。
  2. 2. 内存访问模式:L1/L2 缓存的命中率(Cache Locality)。

我们的目标很明确:找出谁是榨干 CPU 性能的皇帝。

3.2 各语言代码实现

设定统一参数:

  • • 计算上限 (LIMIT): 10,000,000 (一千万)
  • • 校验逻辑: 计算该范围内素数的总个数(应为 664,579),并打印到控制台以防止编译器消除死代码。
  • • 算法: 标准埃拉托色尼筛法 (Sieve of Eratosthenes)。

1. C (GCC)

使用 malloc 分配内存,使用 char 数组(每个字节存一个标志位)。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define LIMIT 10000000int main() {    // 使用 char 数组,比 int 节省内存,且比位操作更利于 CPU 流水线    char *sieve = (char *)malloc(LIMIT + 1);    if (!sieve) return 1;    // 初始化:假设都是素数 (1)    memset(sieve, 1, LIMIT + 1);    sieve[0] = 0;    sieve[1] = 0;    int sqrt_limit = (int)sqrt(LIMIT);    for (int i = 2; i <= sqrt_limit; ++i) {        if (sieve[i]) {            // 从 i*i 开始筛选            for (int j = i * i; j <= LIMIT; j += i) {                sieve[j] = 0;            }        }    }    int count = 0;    for (int i = 0; i <= LIMIT; ++i) {        if (sieve[i]) {            count++;        }    }    printf("Primes found: %d\n", count);    free(sieve);    return 0;}

2. C++ (G++)

使用 std::vector<char>。注意这里不使用 std::vector<bool>,因为 vector<bool> 是位压缩特化版,虽然省内存但在某些 CPU 上解压缩会有额外开销,为了与 C 对标,我们使用字节存储。

#include <iostream>#include <vector>#include <cmath>const int LIMIT = 10000000;int main(){    // 使用 vector<char> 代替 vector<bool> 以获得更好的 CPU 缓存亲和性    // 并避免位操作开销    std::vector<char> sieve(LIMIT + 1, 1);    sieve[0] = 0;    sieve[1] = 0;    int sqrt_limit = std::sqrt(LIMIT);    for (int i = 2; i <= sqrt_limit; ++i) {        if (sieve[i]) {            for (int j = i * i; j <= LIMIT; j += i) {                sieve[j] = 0;            }        }    }    int count = 0;    for (int i = 0; i <= LIMIT; ++i) {        if (sieve[i]) {            count++;        }    }    std::cout << "Primes found: " << count << std::endl;    return 0;}

3. Rust

Rust 的迭代器优化非常出色,但为了算法逻辑一致性,这里采用切片操作。

fn main() {    const LIMIT: usize = 10_000_000;    // vec![true; N] 在 Rust 中非常高效    let mut sieve = vec![true; LIMIT + 1];    sieve[0] = false;    sieve[1] = false;    let sqrt_limit = (LIMIT as f64).sqrt() as usize;    for i in 2..=sqrt_limit {        if sieve[i] {            // Step loop            let mut j = i * i;            while j <= LIMIT {                sieve[j] = false;                j += i;            }        }    }    let count: usize = sieve.iter().filter(|&&x| x).count();    println!("Primes found: {}", count);}

4. Go

Go 的切片操作和 Bounds check(边界检查)是性能考量点。

package mainimport (    "fmt"    "math")const LIMIT = 10000000func main() {    sieve := make([]bool, LIMIT+1)    // 初始化,Go 默认是 false,我们反过来逻辑或者手动置 true    // 为了方便,先手动置 true    for i := 0; i <= LIMIT; i++ {        sieve[i] = true    }    sieve[0] = false    sieve[1] = false    sqrtLimit := int(math.Sqrt(float64(LIMIT)))    for i := 2; i <= sqrtLimit; i++ {        if sieve[i] {            for j := i * i; j <= LIMIT; j += i {                sieve[j] = false            }        }    }    count := 0    for i := 0; i <= LIMIT; i++ {        if sieve[i] {            count++        }    }    fmt.Printf("Primes found: %d\n", count)}

5. ASM (NASM x64)

为了适配 Makefile 中直接使用 ld 链接且不依赖 libc 的情况,这里使用 Linux System Calls (sys_mmap, sys_write, sys_exit) 实现。这展示了极致的无依赖环境。

; 纯汇编实现 Sieve of Eratosthenes (Linux x86_64); 不依赖 C 标准库,直接使用 syscallglobal _startsection .data    limit       equ 10000000    msg_prefix  db "Primes found: ", 0    newline     db 10section .bss    ; 预留一个缓冲区用于将数字转换为字符串打印    buffer      resb 32section .text_start:    ; ==========================================    ; 1. 分配内存 (sys_mmap)    ; size = LIMIT + 1 bytes    ; ==========================================    mov rax, 9          ; sys_mmap    mov rdi, 0          ; addr = NULL    mov rsi, limit + 1  ; length    mov rdx, 3          ; prot = PROT_READ | PROT_WRITE    mov r10, 34         ; flags = MAP_PRIVATE | MAP_ANONYMOUS    mov r8, -1          ; fd    mov r9, 0           ; offset    syscall    test rax, rax       ; check if mmap failed    js .exit_error    mov r12, rax        ; r12 保存数组基地址 (pointer to sieve)    ; ==========================================    ; 2. 初始化数组    ; 将所有字节设为 1 (true)    ; ==========================================    mov rdi, r12    mov rcx, limit + 1    mov al, 1    rep stosb           ; memset(r12, 1, limit+1)    ; sieve[0] = 0, sieve[1] = 0    mov byte [r12], 0    mov byte [r12 + 1], 0    ; ==========================================    ; 3. 筛选逻辑    ; ==========================================    mov rbx, 2          ; rbx = i (current prime candidate).outer_loop:    ; if (i * i > limit) break    mov rax, rbx    mul rbx             ; rax = i * i    cmp rax, limit    ja .count_primes    ; 超过 sqrt(limit),停止筛选    ; if (sieve[i] == 0) continue    cmp byte [r12 + rbx], 0    je .next_outer    ; 内层循环: j = i * i    mov r13, rax        ; r13 = j.inner_loop:    cmp r13, limit    ja .next_outer      ; if j > limit, break inner    mov byte [r12 + r13], 0 ; sieve[j] = 0    add r13, rbx        ; j += i    jmp .inner_loop.next_outer:    inc rbx    jmp .outer_loop    ; ==========================================    ; 4. 统计结果    ; ==========================================.count_primes:    xor r14, r14        ; r14 = count    xor rbx, rbx        ; rbx = index.count_loop:    cmp rbx, limit    ja .print_result    cmp byte [r12 + rbx], 1    jne .next_count    inc r14             ; count++.next_count:    inc rbx    jmp .count_loop    ; ==========================================    ; 5. 打印结果 (Int -> String -> Stdout)    ; ==========================================.print_result:    ; 打印前缀    mov rax, 1    mov rdi, 1    mov rsi, msg_prefix    mov rdx, 14    syscall    ; 将 r14 (count) 转换为字符串    mov rax, r14    mov rdi, buffer + 31 ; 指向 buffer 末尾    mov byte [rdi], 0    ; 字符串结束符 (虽不需要打印)    mov rcx, 10          ; 除数.itoa_loop:    xor rdx, rdx    div rcx              ; rax / 10, rem in rdx    add dl, '0'    dec rdi    mov [rdi], dl    test rax, rax    jnz .itoa_loop    ; 计算长度    mov rsi, rdi         ; 字符串起始地址    lea rdx, [buffer+31]    sub rdx, rsi         ; 长度    ; 打印数字    mov rax, 1           ; sys_write    mov rdi, 1           ; stdout    syscall    ; 打印换行    mov rax, 1    mov rdi, 1    mov rsi, newline    mov rdx, 1    syscall    ; ==========================================    ; 6. 退出    ; ==========================================    mov rax, 60          ; sys_exit    xor rdi, rdi         ; status 0    syscall.exit_error:    mov rax, 60    mov rdi, 1    syscall

6. Java

Java 的 boolean[] 内部通常每个元素占 1 字节(取决于 JVM 实现,但通常如此),这里考察 JVM 的逃逸分析和边界检查消除能力。

public class Primes {    private static final int LIMIT = 10_000_000;    public static void main(String[] args) {        boolean[] sieve = new boolean[LIMIT + 1];        // Java 默认为 false,我们反转逻辑或手动置 true        // 手动置 true        for (int i = 0; i <= LIMIT; i++) {            sieve[i] = true;        }        sieve[0] = false;        sieve[1] = false;        int sqrtLimit = (int) Math.sqrt(LIMIT);        for (int i = 2; i <= sqrtLimit; i++) {            if (sieve[i]) {                for (int j = i * i; j <= LIMIT; j += i) {                    sieve[j] = false;                }            }        }        int count = 0;        for (int i = 0; i <= LIMIT; i++) {            if (sieve[i]) {                count++;            }        }        System.out.println("Primes found: " + count);    }}

7. C# (.NET Core)

使用 .NET 顶级语句(Top-level statements)简化代码。

using System;const int LIMIT = 10_000_000;bool[] sieve = new bool[LIMIT + 1];// Fill trueArray.Fill(sieve, true);sieve[0] = false;sieve[1] = false;int sqrtLimit = (int)Math.Sqrt(LIMIT);for (int i = 2; i <= sqrtLimit; i++){    if (sieve[i])    {        for (int j = i * i; j <= LIMIT; j += i)        {            sieve[j] = false;        }    }}int count = 0;for (int i = 0; i <= LIMIT; i++){    if (sieve[i])    {        count++;    }}Console.WriteLine($"Primes found: {count}");

需要配套的项目文件:

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>net10.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>    <!-- 开启 AOT 可以获得更好的启动和运行性能,但此处默认 JIT 即可 -->  </PropertyGroup></Project>

8. Node.js (JavaScript)

使用 Uint8Array 模拟 C 风格的内存布局,比标准 Array 快得多。

const LIMIT = 10000000;function run() {    // Uint8Array 初始化默认为 0    // 我们定义 1 为素数,0 为非素数,或者反过来。    // 为了和 C 代码一致,我们先全部填 1    const sieve = new Uint8Array(LIMIT + 1);    sieve.fill(1);    sieve[0] = 0;    sieve[1] = 0;    const sqrtLimit = Math.floor(Math.sqrt(LIMIT));    for (let i = 2; i <= sqrtLimit; i++) {        if (sieve[i] === 1) {            for (let j = i * i; j <= LIMIT; j += i) {                sieve[j] = 0;            }        }    }    let count = 0;    for (let i = 0; i <= LIMIT; i++) {        if (sieve[i] === 1) {            count++;        }    }    console.log(`Primes found: ${count}`);}run();

9. Python

使用 bytearray,它是 Python 中可变的字节序列,比 list 更省内存且稍快。

import mathLIMIT = 10_000_000def main():    # bytearray 初始化为 1 (True)    sieve = bytearray([1]) * (LIMIT + 1)    sieve[0] = 0    sieve[1] = 0    sqrt_limit = int(math.isqrt(LIMIT))    for i in range(2, sqrt_limit + 1):        if sieve[i]:            # 切片赋值通常比循环快,但在筛法中步长不为1            # Python 的 range 步长赋值 sieve[i*i::i] = ...             # 是极致优化的关键,比 while loop 快很多            sieve[i*i : LIMIT+1 : i] = bytes([0]) * len(sieve[i*i : LIMIT+1 : i])    # sum(sieve) 统计所有为 1 的字节    count = sum(sieve)    print(f"Primes found: {count}")if __name__ == "__main__":    main()

注:Python 代码特意使用了切片赋值优化 (sieve[start:end:step]),这是 Pythonic 的写法,否则纯 Python for 循环性能会极其低下,无法体现 Python 在科学计算中的实际用法。


10. PHP

使用 SplFixedArray 或者字符串操作。在 PHP 中,操作大数组非常耗内存。为了性能测试,我们使用 SplFixedArray,这是 PHP 标准库中用于优化数组性能的类。

<?phpconst LIMIT = 10000000;// 使用 SplFixedArray 比普通 array 省内存且快$sieve = new SplFixedArray(LIMIT + 1);// 初始化:默认是 null,手动置 truefor ($i = 0; $i <= LIMIT; $i++) {    $sieve[$i] = true;}$sieve[0] = false;$sieve[1] = false;$sqrtLimit = (int)sqrt(LIMIT);for ($i = 2; $i <= $sqrtLimit; $i++) {    if ($sieve[$i]) {        for ($j = $i * $i; $j <= LIMIT; $j += $i) {            $sieve[$j] = false;        }    }}$count = 0;for ($i = 0; $i <= LIMIT; $i++) {    if ($sieve[$i]) {        $count++;    }}echo "Primes found: $count" . PHP_EOL;

3.3 hyperfine 测试结果对比

场景一
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
C++
22.0 ± 2.0
19.1
30.1
1.00
C
23.1 ± 3.8
18.5
39.6
1.05 ± 0.20
Rust
23.3 ± 4.6
18.8
60.5
1.06 ± 0.23
ASM
29.9 ± 3.8
24.8
44.6
1.36 ± 0.21
Go
34.0 ± 3.6
29.4
55.6
1.54 ± 0.21
NodeJS
72.0 ± 15.6
62.0
158.1
3.26 ± 0.76
C#
74.8 ± 6.9
68.4
98.2
3.39 ± 0.43
Java
78.2 ± 3.9
71.7
88.2
3.55 ± 0.36
Python
100.6 ± 19.1
86.9
193.9
4.56 ± 0.96
PHP
768.0 ± 153.4
670.8
1026.3
34.84 ± 7.62

3.4 结果分析:人类的一败涂地

1. “三巨头”的窒息操作 (C++ / C / Rust)

毫无悬念,C++、C 和 Rust 霸占了前三名,它们之间的差距仅在 1ms 左右,考虑到系统抖动,这几乎就是平局。

  • • G++ 的胜利:C++ 险胜 C 语言 1ms,这再次证明了现代 C++ (std::vector + -O3) 的零成本抽象不是谎言。
  • • Rust 的稳健:在保证内存安全的前提下(虽然我们在代码中用了 Vec,但编译器很聪明地消除了大部分边界检查),Rust 依然紧咬 C/C++。

2. 汇编 (ASM):尴尬的“手艺人”

这可能是最让底层极客心碎的一幕:手写的汇编代码 (29.9ms) 竟然输给了编译器生成的代码 (22.0ms)。为什么?因为 GCC 15 和 LLVM 19 实在太聪明了。编译器能够自动进行极其激进的循环展开 (Loop Unrolling) 和 SIMD 向量化指令优化 (AVX2/AVX-512)。除非你是汇编世界级的专家,精通每一级流水线的延迟,否则很难手工打败 -O3 开启后的编译器。结论:在 2026 年,相信编译器通常比相信自己的手速更明智。

3. Node.js 的逆袭与 JIT 混战

在托管语言梯队中,Node.js (V8 引擎) 竟然以微弱优势领先了 C# 和 Java,排到了第 6 位!

  • • 这归功于我们使用了 Uint8Array。V8 引擎对 TypedArray 的优化已经到了变态的地步,几乎将其直接映射为底层内存操作。
  • • Java 和 C# 虽然有强大的 JIT,但在这个极其简单的数组操作场景下,对象头的开销和运行时检查稍微拖了后腿。不过 70ms 级别的耗时,对于解释型/JIT 语言来说已经是非常优秀的成绩。

4. Python 的“作弊”与 PHP 的“躺平”

  • • Python (100ms):怎么可能只比 C++ 慢 4.5 倍?通常 Python 的循环不都是慢 50-100 倍吗?这里有一个关键点:我们的 Python 代码使用了 Slice Assignment (sieve[i*i::i] = ...)。这行代码实际上是让 Python 解释器调用了底层的 C 语言循环进行内存赋值。如果我们写的是 while 循环,它的时间绝对会飙升到 2 秒以上。这告诉我们:写 Python 高性能代码的秘诀,就是尽量别写 Python 循环。
  • • PHP (768ms):PHP 在这里显得有些格格不入,慢了 C++ 整整 34 倍。尽管开启了 Opcache,尽管使用了 SplFixedArray,但在密集 CPU 计算领域,PHP 依然是“由于语言特性退出直播间”。术业有专攻,我们还是让它安心处理 HTTP 请求吧。

4. 场景二:递归与内存栈性能 —— 斐波那契数列 (Fibonacci)

4.1 只有 CPU 受伤的世界

如果说上一轮的质数筛选是平原上的百米冲刺,那么计算 Fib(40) 就是在垂直的悬崖上做引体向上。

我们采用最朴素的递归实现(Naive Recursive),不使用任何记忆化(Memoization)或尾递归优化技巧。计算 Fib(40) 需要进行超过 2 亿次 的函数调用。这意味着 CPU 的栈指针(Stack Pointer)将经历数亿次的疯狂跳动,每一次 call 和 ret 都在考验语言运行时的:

  1. 1. 函数调用开销 (Overhead):压栈、保存寄存器、分配栈帧。
  2. 2. 栈溢出风险管理:运行时如何检测堆栈深度。

4.2 各语言代码实现

设定统一参数:

  • • 输入值 (N): 40
  • • 算法: 朴素递归 (Naive Recursive),不使用记忆化或尾递归优化,强制测试函数调用开销。
  • • 预期结果: Fib(40) = 102,334,155

1. C (GCC)

#include <stdio.h>#include <stdlib.h>long fib(long n) {    if (n <= 1) return n;    return fib(n - 1) + fib(n - 2);}int main(int argc, char *argv[]) {    long n = 40;    if (argc > 1) {        n = atol(argv[1]);    }    long result = fib(n);    printf("Fib(%ld) = %ld\n", n, result);    return 0;}

2. C++ (G++)

#include <iostream>#include <string>long fib(long n){    if (n <= 1) return n;    return fib(n - 1) + fib(n - 2);}int main(int argc, char* argv[]){    long n = 40;    if (argc > 1) {        n = std::stol(argv[1]);    }    long result = fib(n);    std::cout << "Fib(" << n << ") = " << result << std::endl;    return 0;}

3. Rust

Rust 默认不保证尾调用优化(即使我们写的是非尾递归代码,这里主要是测试栈分配)。

use std::env;fn fib(n: u64) -> u64 {    if n <= 1 {        return n;    }    fib(n - 1) + fib(n - 2)}fn main() {    let args: Vec<String> = env::args().collect();    let n = if args.len() > 1 {        args[1].parse().unwrap_or(40)    } else {        40    };    let result = fib(n);    println!("Fib({}) = {}", n, result);}

4. Go

Go 使用分段栈(或移动栈),其函数调用开销通常极小,但在深度递归下可能会有栈扩容的开销。

package mainimport (    "fmt"    "os"    "strconv")func fib(n int) int {    if n <= 1 {        return n    }    return fib(n-1) + fib(n-2)}func main() {    n := 40    if len(os.Args) > 1 {        if val, err := strconv.Atoi(os.Args[1]); err == nil {            n = val        }    }    result := fib(n)    fmt.Printf("Fib(%d) = %d\n", n, result)}

5. ASM (NASM x64)

使用 System V AMD64 ABI 调用约定。递归逻辑中需要频繁压栈保存 rbx 和 n

; 递归计算 Fibonacci(40); 纯汇编实现,不依赖 libcglobal _startsection .data    n_default   equ 40    msg_part1   db "Fib(", 0    msg_part2   db ") = ", 0    newline     db 10section .bss    buffer      resb 32section .text_start:    ; 设置计算数值,默认 40    mov rdi, n_default    ; 保存 n 以备后用打印    mov r15, rdi     ; 调用 fib(n)    call fib    ; 结果在 rax 中,保存到 r14    mov r14, rax    ; --- 打印输出逻辑 ---    ; 打印 "Fib("    mov rax, 1    mov rdi, 1    mov rsi, msg_part1    mov rdx, 4    syscall    ; 打印 N (r15)    mov rax, r15    call print_number    ; 打印 ") = "    mov rax, 1    mov rdi, 1    mov rsi, msg_part2    mov rdx, 4    syscall    ; 打印 Result (r14)    mov rax, r14    call print_number    ; 打印换行    mov rax, 1    mov rdi, 1    mov rsi, newline    mov rdx, 1    syscall    ; 退出    mov rax, 60    xor rdi, rdi    syscall; -----------------------------------; long fib(long n); Input: rdi; Output: rax; -----------------------------------fib:    cmp rdi, 1    jle .base_case    ; 递归步骤: fib(n-1) + fib(n-2)    push rbx        ; 保存被调用者保存寄存器    push rdi        ; 保存当前 n    dec rdi         ; n = n - 1    call fib        ; rax = fib(n-1)    mov rbx, rax    ; rbx = fib(n-1)    pop rdi         ; 恢复 n    sub rdi, 2      ; n = n - 2    call fib        ; rax = fib(n-2)    add rax, rbx    ; rax = fib(n-2) + fib(n-1)    pop rbx         ; 恢复 rbx    ret.base_case:    mov rax, rdi    ret; -----------------------------------; 辅助函数: 打印 rax 中的数字; -----------------------------------print_number:    mov rdi, buffer + 31    mov byte [rdi], 0    mov rcx, 10.itoa_loop:    xor rdx, rdx    div rcx    add dl, '0'    dec rdi    mov [rdi], dl    test rax, rax    jnz .itoa_loop    mov rsi, rdi    lea rdx, [buffer+31]    sub rdx, rsi    mov rax, 1    mov rdi, 1    syscall    ret

6. Java

Java 的方法调用通过栈帧实现,较深层次的递归可能触及默认栈大小限制(但在 N=40 时通常安全)。

public class Fib {    public static long fib(int n) {        if (n <= 1) return n;        return fib(n - 1) + fib(n - 2);    }    public static void main(String[] args) {        int n = 40;        if (args.length > 0) {            try {                n = Integer.parseInt(args[0]);            } catch (NumberFormatException e) {                // ignore            }        }        long result = fib(n);        System.out.println("Fib(" + n + ") = " + result);    }}

7. C# (.NET Core)

using System;class Program{static long Fib(int n)    {        if (n <= 1) return n;        return Fib(n - 1) + Fib(n - 2);    }static void Main(string[] args)    {        int n = 40;        if (args.Length > 0)        {            int.TryParse(args[0], out n);        }        long result = Fib(n);        Console.WriteLine($"Fib({n}) = {result}");    }}

配套项目文件:

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>net10.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>  </PropertyGroup></Project>

8. Node.js (JavaScript)

V8 引擎虽然对递归有优化,但对于这种无法 TCO(尾调用优化)的朴素递归,依然是纯粹考察函数栈的开销。

function fib(n) {    if (n <= 1) return n;    return fib(n - 1) + fib(n - 2);}const args = process.argv.slice(2);const n = args.length > 0 ? parseInt(args[0]) : 40;const result = fib(n);console.log(`Fib(${n}) = ${result}`);

9. Python

Python 的函数调用开销在动态语言中是众所周知的性能杀手。N=40 对 Python 来说会显著慢于编译型语言。

import sysdef fib(n):    if n <= 1:        return n    return fib(n - 1) + fib(n - 2)if __name__ == "__main__":    n = 40    if len(sys.argv) > 1:        try:            n = int(sys.argv[1])        except ValueError:            pass    result = fib(n)    print(f"Fib({n}) = {result}")

10. PHP

PHP 的递归深度和函数调用开销与 Python 类似,属于脚本语言梯队。

<?phpfunction fib($n{    if ($n <= 1) return $n;    return fib($n - 1) + fib($n - 2);}$n = 40;if ($argc > 1) {    $n = (int)$argv[1];}$result = fib($n);echo "Fib($n) = $result" . PHP_EOL;

4.3 hyperfine 测试结果对比

场景二
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
C++
134.5 ± 7.6
125.9
153.3
1.00
C
135.7 ± 6.4
125.2
150.7
1.01 ± 0.07
Rust
272.3 ± 14.9
257.9
297.4
2.03 ± 0.16
Java
355.7 ± 15.9
341.5
385.2
2.65 ± 0.19
C#
406.2 ± 8.8
395.4
418.2
3.02 ± 0.18
Go
451.6 ± 9.9
444.3
470.9
3.36 ± 0.20
ASM
484.8 ± 2.1
481.1
487.4
3.61 ± 0.21
NodeJS
1001.0 ± 12.0
988.9
1017.3
7.44 ± 0.43
PHP
4057.1 ± 95.5
3922.2
4168.1
30.17 ± 1.85
Python
8961.5 ± 348.1
8488.9
9469.5
66.65 ± 4.58

4.4 结果分析:谁的“栈”最痛?

1. C/C++ 的统治力与 Rust 的“安全税”

C 和 C++ 再次毫无悬念地以 ~135ms 夺冠。GCC 15 在 -O3 下对这种纯计算递归进行了极致的优化,甚至可能内联了部分基准情形,使得函数调用的开销微乎其微。

然而,Rust (272ms) 竟然慢了整整一倍!这并非 Rust 语言本身慢,而是“安全”的代价。Rust 在每次函数调用时,默认会进行更严格的栈溢出检查(Stack Probe),且 LLVM 对 Rust 这种递归模式的优化策略可能不如 C 激进。在数亿次调用中,每一次微小的安全检查累积起来,就变成了 100% 的额外开销。

2. 汇编 (ASM) 的“耻辱性”溃败

大家请看数据:ASM (485ms) 甚至输给了 Java (356ms) 和 C# (406ms)。这绝对是本次评测最大的“打脸”现场。

  • • 为什么? 我手写的 ASM 代码忠实地执行了 push rbxcall fibpop rbxret 标准流程。
  • • Java 做了什么? JVM 的 C2 编译器(JIT)识别出了这是热点代码,它不仅进行了机器码编译,甚至可能在运行时动态改变了内联策略,或者使用了比标准 ABI 更高效的寄存器传参方式。
  • • 教训:除非你打算手工优化每一条指令流水线,否则别试图用手写汇编去挑战经过三十年优化的 JVM JIT 编译器,尤其是在递归这种复杂场景下。

3. Go 的分段栈之痛

Go 语言 (451ms) 在这里表现平平,甚至略逊于 ASM。Go 为了支持海量 Goroutine,使用的是动态扩缩容的栈(初始很小,不够用时分配更大的并拷贝)。这种机制在并发时是神器,但在深度递归(Fib(40) 深度其实尚可,但调用频率极高)时,栈检查和管理的开销就显现出来了。

4. Python 的“地质年代”

如果把 C++ 的 135ms 看作是博尔特跑完 100 米,那么 Python 的 8.9 秒 就像是……刚跑出起跑线然后在地上睡了一觉。

  • • 66 倍的差距。这是因为 Python 的每一次函数调用都是一次沉重的操作:创建栈帧对象、更新引用计数、处理动态类型……
  • • Node.js (1s):表现尚可,V8 引擎虽然无法完全消除动态语言的开销,但至少把差距控制在了 10 倍以内。
  • • PHP (4s):比 Python 快了一倍,但在现代编程性能基准中,4 秒依然是一个漫长的等待。

结论:如果你需要写递归算法,请以此为戒:要么用 C++/Java 重写,要么请务必加上 @lru_cache (Python) 或自行实现记忆化。 裸奔的递归,在脚本语言中就是 CPU 的火葬场。

5. 场景三:I/O 密集型操作 —— 大文件处理

5.1 搬运工的较量

如果说前两个场景是在考查大脑的算力,那么 I/O 密集型测试就是在考查“搬砖”的速度。

在这个场景中,我们生成了一个 1GB 的文本日志文件。程序的任务看似简单:从硬盘读取数据,统计行数,并检查每一行是否包含特定的版权声明字符串。但这背后隐藏着操作系统与用户态程序之间的博弈:

  1. 1. Syscall 开销:每次读取需要多少次系统调用?
  2. 2. 内存拷贝:数据从内核态到用户态,再到应用程序的字符串对象,复制了多少次?
  3. 3. 编码转换:特别是对于 Java/C# 这种内部使用 UTF-16 的语言,将磁盘上的 UTF-8 转码也是隐形杀手。

5.2 各语言代码实现

设定统一参数:

  • • 目标文件scene3_io_file/test_data.txt (由 Python 脚本生成,约 1GB)
  • • 任务逻辑: 逐行读取文件,统计 总行数,并统计包含子字符串 "Copyright" 的行数。
  • • 关键点: 使用缓冲读取 (Buffered IO) 避免一次性加载到内存。

0. 数据生成脚本 (Python)

此脚本用于生成测试用的 1GB 文本文件。

import osFILE_PATH = os.path.join(os.path.dirname(__file__), "test_data.txt")TARGET_SIZE = 1024 * 1024 * 1024  # 1 GBdef main():    if os.path.exists(FILE_PATH):        print(f"File {FILE_PATH} already exists. Skipping generation.")        return    print(f"Generating ~1GB file at {FILE_PATH}...")    # 模拟日志行    lines = [        "2026-01-12 10:00:00 INFO  System starting up, initialization sequence began.\n",        "2026-01-12 10:00:01 WARN  Memory usage slightly high, running GC.\n",        "2026-01-12 10:00:02 ERROR Connection timeout while reaching database 192.168.1.50.\n",        "2026-01-12 10:00:03 INFO  User logged in from IP 10.0.0.1.\n",        "2026-01-12 10:00:04 DEBUG Payload received: { 'id': 123, 'status': 'active' }.\n",        "2026-01-12 10:00:05 INFO  Copyright (c) 2026 Benchmark Corp. All rights reserved.\n", # Target line        "2026-01-12 10:00:06 INFO  Scheduled maintenance task completed successfully.\n",        "2026-01-12 10:00:07 TRACE Stack trace dumped to /var/log/crash.log.\n"    ]    current_size = 0    with open(FILE_PATH, "w", encoding="utf-8") as f:        while current_size < TARGET_SIZE:            for line in lines:                f.write(line)                current_size += len(line)    print("Generation complete.")if __name__ == "__main__":    main()

1. C (GCC)

使用 fopen 和 fgets,并手动设置 64KB 缓冲区以减少 syscall 次数。

#include <stdio.h>#include <stdlib.h>#include <string.h>#define BUFFER_SIZE 65536#define FILE_PATH "scene3_io_file/test_data.txt"#define TARGET_STR "Copyright"int main() {    FILE *fp = fopen(FILE_PATH, "r");    if (!fp) {        perror("Error opening file");        return 1;    }    // 设置大缓冲区优化 I/O    char *buffer = (char *)malloc(BUFFER_SIZE);    if (setvbuf(fp, buffer, _IOFBF, BUFFER_SIZE) != 0) {        perror("Failed to set buffer");        return 1;    }    // 用于存储单行的缓冲区    char line_buf[4096];    long long total_lines = 0;    long long match_count = 0;    while (fgets(line_buf, sizeof(line_buf), fp)) {        total_lines++;        if (strstr(line_buf, TARGET_STR) != NULL) {            match_count++;        }    }    printf("Total lines: %lld\n", total_lines);    printf("Matches found: %lld\n", match_count);    free(buffer);    fclose(fp);    return 0;}

2. C++ (G++)

关闭 sync_with_stdio 以提升 cin/fstream 性能。

#include <iostream>#include <fstream>#include <string>#include <vector>const std::string FILE_PATH = "scene3_io_file/test_data.txt";const std::string TARGET_STR = "Copyright";int main(){    // 性能关键:解除 C++ stream 与 C stdio 的同步    std::ios::sync_with_stdio(false);    std::cin.tie(nullptr);    std::ifstream file(FILE_PATH);    if (!file.is_open()) {        std::cerr << "Error opening file" << std::endl;        return 1;    }    // 设置 64KB 缓冲区    char buf[65536];    file.rdbuf()->pubsetbuf(buf, sizeof(buf));    std::string line;    // 预分配 string 内存以减少 realloc,虽然 getline 会自动管理    line.reserve(1024);    long long total_lines = 0;    long long match_count = 0;    while (std::getline(file, line)) {        total_lines++;        if (line.find(TARGET_STR) != std::string::npos) {            match_count++;        }    }    std::cout << "Total lines: " << total_lines << "\n";    std::cout << "Matches found: " << match_count << std::endl;    return 0;}

3. Rust

使用 BufReader 和 lines() 迭代器。

use std::fs::File;use std::io::{self, BufRead, BufReader};const FILE_PATH: &str = "scene3_io_file/test_data.txt";const TARGET_STR: &str = "Copyright";fn main() -> io::Result<()> {    let file = File::open(FILE_PATH)?;    // Rust 默认 BufReader 缓冲区是 8KB,这里显式设为 64KB    let reader = BufReader::with_capacity(65536, file);    let mut total_lines = 0;    let mut match_count = 0;    for line_result in reader.lines() {        let line = line_result?;        total_lines += 1;        if line.contains(TARGET_STR) {            match_count += 1;        }    }    println!("Total lines: {}", total_lines);    println!("Matches found: {}", match_count);    Ok(())}

4. Go

使用 bufio.Scanner 是最惯用的方式,但对于超长行可能会报错。鉴于测试数据行长度可控,这里使用 Scanner

package mainimport (    "bufio"    "fmt"    "os"    "strings")const FILE_PATH = "scene3_io_file/test_data.txt"const TARGET_STR = "Copyright"func main() {    file, err := os.Open(FILE_PATH)    if err != nil {        panic(err)    }    defer file.Close()    // 默认缓冲区 4KB,Scanner 内部可增长    scanner := bufio.NewScanner(file)    // 分配一个更大的初始 Buffer 可以稍微提升性能    buf := make([]byte, 64*1024)    scanner.Buffer(buf, 10*1024*1024) // max 10MB line    var totalLines int64 = 0    var matchCount int64 = 0    for scanner.Scan() {        totalLines++        // Bytes() 比 Text() 少一次 string 分配,        // 但为了包含 substring 检查逻辑的公平性,使用 string 检查        if strings.Contains(scanner.Text(), TARGET_STR) {            matchCount++        }    }    if err := scanner.Err(); err != nil {        fmt.Fprintln(os.Stderr, "reading standard input:", err)    }    fmt.Printf("Total lines: %d\n", totalLines)    fmt.Printf("Matches found: %d\n", matchCount)}

5. Java

使用 BufferedReader

import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class IoTest {    private static final String FILE_PATH = "scene3_io_file/test_data.txt";    private static final String TARGET_STR = "Copyright";    public static void main(String[] args) {        long totalLines = 0;        long matchCount = 0;        // 设置 64KB 缓冲区        try (BufferedReader br = new BufferedReader(new FileReader(FILE_PATH), 65536)) {            String line;            while ((line = br.readLine()) != null) {                totalLines++;                if (line.contains(TARGET_STR)) {                    matchCount++;                }            }        } catch (IOException e) {            e.printStackTrace();            return;        }        System.out.println("Total lines: " + totalLines);        System.out.println("Matches found: " + matchCount);    }}

6. C# (.NET Core)

使用 StreamReader 逐行读取。

using System;using System.IO;const string FILE_PATH = "scene3_io_file/test_data.txt";const string TARGET_STR = "Copyright";if (!File.Exists(FILE_PATH)){    Console.WriteLine("File not found.");    return;}long totalLines = 0;long matchCount = 0;// BufferSize = 64KBusing (var sr = new StreamReader(FILE_PATH, new FileStreamOptions { Mode = FileMode.Open, Access = FileAccess.Read, BufferSize = 65536 })){    string? line;    while ((line = sr.ReadLine()) != null)    {        totalLines++;        if (line.Contains(TARGET_STR))        {            matchCount++;        }    }}Console.WriteLine($"Total lines: {totalLines}");Console.WriteLine($"Matches found: {matchCount}");

配套项目文件:

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>net10.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>  </PropertyGroup></Project>

7. Node.js (JavaScript)

使用 fs.createReadStream 配合 readline 模块,这是 Node 处理大文件的标准方式。

const fs = require('fs');const readline = require('readline');const path = 'scene3_io_file/test_data.txt';const targetStr = 'Copyright';async function processFile() {    const fileStream = fs.createReadStream(path, {        highWaterMark: 64 * 1024, // 64KB chunk        encoding: 'utf8'    });    const rl = readline.createInterface({        input: fileStream,        crlfDelay: Infinity    });    let totalLines = 0;    let matchCount = 0;    for await (const line of rl) {        totalLines++;        if (line.includes(targetStr)) {            matchCount++;        }    }    console.log(`Total lines: ${totalLines}`);    console.log(`Matches found: ${matchCount}`);}processFile();

8. Python

Python 的文件迭代器已经非常优化,通常自带 buffering。

FILE_PATH = "scene3_io_file/test_data.txt"TARGET_STR = "Copyright"def main():    total_lines = 0    match_count = 0    try:        # buffering > 1 表示 buffer size,这里设为 64KB        with open(FILE_PATH, 'r', encoding='utf-8', buffering=65536) as f:            for line in f:                total_lines += 1                if TARGET_STR in line:                    match_count += 1    except FileNotFoundError:        print("File not found. Please run generate_data.py first.")        return    print(f"Total lines: {total_lines}")    print(f"Matches found: {match_count}")if __name__ == "__main__":    main()

9. PHP

使用 fgets 逐行读取。

<?phpdefine('FILE_PATH', 'scene3_io_file/test_data.txt');define('TARGET_STR', 'Copyright');if (!file_exists(FILE_PATH)) {    echo "File not found.\n";    exit(1);}$handle = fopen(FILE_PATH, "r");if ($handle) {    // 设置流 chunk 大小    stream_set_chunk_size($handle, 65536);    $totalLines = 0;    $matchCount = 0;    while (($line = fgets($handle)) !== false) {        $totalLines++;        // strict check is not needed for simple contains        if (strpos($line, TARGET_STR) !== false) {            $matchCount++;        }    }    fclose($handle);    echo "Total lines: $totalLines\n";    echo "Matches found: $matchCount\n";} else {    echo "Error opening file.\n";}

5.3 hyperfine 测试结果对比

场景三
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
C
498.7 ± 146.7
382.7
723.1
1.00
C++
547.4 ± 34.8
517.5
596.1
1.10 ± 0.33
Rust
735.0 ± 31.6
705.0
785.6
1.47 ± 0.44
Go
826.2 ± 77.9
716.8
931.2
1.66 ± 0.51
PHP
918.2 ± 23.4
889.6
945.4
1.84 ± 0.54
C#
1022.2 ± 43.3
979.9
1087.4
2.05 ± 0.61
Java
1410.0 ± 143.4
1273.4
1653.2
2.83 ± 0.88
Python
1563.8 ± 94.1
1450.6
1644.4
3.14 ± 0.94
NodeJS
2955.2 ± 91.7
2792.2
3006.9
5.93 ± 1.75

5.4 结果分析:PHP 的逆袭与 Node.js 的滑铁卢

1. C/C++:贴地飞行的艺术

C 语言 (498ms) 和 C++ (547ms) 再次证明了它们是系统编程的王者。C 语言的高方差(±146ms)主要源于操作系统文件缓存(Page Cache)的状态波动,但其极值性能(382ms)简直令人咋舌。这意味着 CPU 几乎没有处理逻辑,时间全花在了内存带宽上。

2. PHP:全场最大的黑马!

请大家起立致敬。PHP (918ms) 竟然击败了 C# (1022ms) 和 Java (1410ms),并且把 Python 和 Node.js 远远甩在身后!

  • • 为什么? 很多人忘了 PHP 的初衷——它就是为了处理文本而生的。PHP 的 fgets 底层直接映射到 C 语言的高效实现,且 PHP 的字符串管理在处理这种“读完即扔”的流水线任务时,并没有复杂的对象开销。它不做复杂的逻辑运算,只是单纯地搬运数据,这时候 PHP 的 C 内核优势就显现出来了。

3. Java 与 C# 的“富贵病”

Java 和 C# 分别跑出了 1.4s 和 1.0s 的成绩,虽然不慢,但输给了 Rust、Go 甚至 PHP。主要原因在于 字符串编码转换 (Encoding Overhead) 和 对象创建 (Object Allocation)

  • • Java 内部使用 UTF-16 存储字符串。从磁盘读取 UTF-8 字节流,必须在内存中解码并转为 UTF-16 char 数组,这需要 CPU 周期。
  • • 每读一行就创建一个 String 对象,对于 1GB 的文件来说,这是数百万个对象的创建与回收,GC(垃圾回收器)虽然很强,但还没强到完全隐形。

4. Node.js:流式处理的痛

Node.js (2.9s) 排名垫底,比 Python 还要慢近一倍。这听起来不合理,Node.js 不是以异步 I/O 著称吗?

  • • 问题不在于 I/O,而在于 边界跨越 (Boundary Crossing)
  • • 我们使用的是 readline 模块逐行处理。这意味着 C++ (libuv) 层每读取到一行数据,就需要将其封装成 JS 对象,跨越 V8 边界回调给 JS 代码。这种高频的“C++ -> JS”上下文切换,在处理数千万行数据时,累积成了巨大的开销。如果是一次性读取整个 Buffer,Node.js 会快得多,但在流式处理上,它确实累了。

5. Rust 与 Go:稳如老狗

Rust (735ms) 和 Go (826ms) 表现得非常稳定,紧随 C/C++ 之后。它们没有 Java 的编码转换包袱,也没有脚本语言的解释开销。Rust 的 BufReader 抽象几乎是零成本的,再次证明了它作为“C++ 继任者”的实力。

6. 场景四:并发与多线程计算 —— 蒙特卡洛估算 Pi

6.1 乱枪打鸟的艺术

并发计算是现代 CPU 的主战场。为了测试多核协同能力,我们选择了 蒙特卡洛方法估算 Pi简单来说,就是让 CPU 闭着眼睛向一个正方形内扔“飞镖”(随机点)。如果飞镖落在内切圆内,就记一分。扔了一亿次飞镖后,通过圆内点数与总点数的比例,就能反推出 Pi 的值。

这个场景的核心考点有三个:

  1. 1. 线程/协程调度开销:创建 8 个并行任务需要多久?
  2. 2. 锁竞争 (Contention):如果你的随机数生成器 (RNG) 是全局锁的(比如老版本的 rand()),那多核反而会变单核。我们要求各语言使用 Thread-local RNG。
  3. 3. 浮点数吞吐量:大量的 double 乘法与加法。

6.2 各语言代码实现

设定统一参数:

  • • 总样本数 (N): 100,000,000 (一亿)
  • • 并发数: 8 线程/进程
  • • 算法: Monte Carlo (随机投点法) 
  • • 关键点: 必须使用 线程独立 (Thread-local) 的随机数生成器,避免锁竞争导致性能回退。

1. C (GCC + Pthreads)

为了避免 rand() 的全局锁性能问题,实现了一个简单的线程级 Xorshift 随机数生成器。

#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <stdint.h>#define TOTAL_ITERATIONS 100000000#define NUM_THREADS 8#define ITERATIONS_PER_THREAD (TOTAL_ITERATIONS / NUM_THREADS)// 简单的快速随机数生成器状态typedefstruct {    uint32_t x;    uint32_t y;    uint32_t z;    uint32_t w;} xorshift128_state;// 初始化种子void xorshift128_init(xorshift128_state *state, uint32_t seed) {    state->x = seed;    state->y = seed * 1812433253 + 1;    state->z = state->y * 1812433253 + 1;    state->w = state->z * 1812433253 + 1;}// 生成随机数 [0, UINT32_MAX]uint32_t xorshift128(xorshift128_state *state) {    uint32_t t = state->x;    t ^= t << 11;    t ^= t >> 8;    state->x = state->y;    state->y = state->z;    state->z = state->w;    state->w = state->w ^ (state->w >> 19) ^ t;    return state->w;}void* worker(void* arg) {    long thread_id = (long)arg;    long long count = 0;    // 线程独立的 RNG 状态    xorshift128_state state;    xorshift128_init(&state, (uint32_t)(thread_id + 12345));    // 预计算最大值的倒数,将除法转为乘法    double scale = 1.0 / (double)UINT32_MAX;    for (int i = 0; i < ITERATIONS_PER_THREAD; i++) {        double x = xorshift128(&state) * scale;        double y = xorshift128(&state) * scale;        if (x * x + y * y <= 1.0) {            count++;        }    }    return (void*)count;}int main() {    pthread_t threads[NUM_THREADS];    long long total_hits = 0;    for (long i = 0; i < NUM_THREADS; i++) {        pthread_create(&threads[i], NULL, worker, (void*)i);    }    for (int i = 0; i < NUM_THREADS; i++) {        void* ret;        pthread_join(threads[i], &ret);        total_hits += (long long)ret;    }    double pi = 4.0 * (double)total_hits / (double)TOTAL_ITERATIONS;    printf("Pi: %.10f\n", pi);    return 0;}

2. C++ (G++ + std::thread)

#include <iostream>#include <vector>#include <thread>#include <atomic>#include <random>const int TOTAL_ITERATIONS = 100000000;const int NUM_THREADS = 8;const int ITERATIONS_PER_THREAD = TOTAL_ITERATIONS / NUM_THREADS;// 使用 atomic 汇总结果std::atomic<long long> global_hits(0);void worker(int seed_offset){    // 线程独立的随机数引擎    // std::mt19937 稍重,这里为了速度使用 minstd_rand (LCG) 或自定义    // 为了性能测试公平性,使用轻量级引擎    std::minstd_rand rng(seed_offset + 12345);    std::uniform_real_distribution<double> dist(0.0, 1.0);    long long local_hits = 0;    for (int i = 0; i < ITERATIONS_PER_THREAD; ++i) {        double x = dist(rng);        double y = dist(rng);        if (x * x + y * y <= 1.0) {            local_hits++;        }    }    global_hits += local_hits;}int main(){    std::vector<std::thread> threads;    for (int i = 0; i < NUM_THREADS; ++i) {        threads.emplace_back(worker, i);    }    for (auto& t : threads) {        t.join();    }    double pi = 4.0 * global_hits / TOTAL_ITERATIONS;    std::cout << "Pi: " << pi << std::endl;    return 0;}

3. Rust (std::thread)

为了不依赖外部 rand crate 导致构建复杂(需要 Cargo.toml),此处内联实现了一个极快的 Xorshift 算法。

use std::thread;const TOTAL_ITERATIONS: usize = 100_000_000;const NUM_THREADS: usize = 8;const ITERATIONS_PER_THREAD: usize = TOTAL_ITERATIONS / NUM_THREADS;// 简单的 Xorshift RNG,避免引入外部依赖struct Xorshift {    state: u32,}impl Xorshift {    fn new(seed: u32) -> Self {        Self { state: if seed == 0 { 1 } else { seed } }    }    // 生成 [0, 1) 的 f64    fn next_f64(&mut self) -> f64 {        let mut x = self.state;        x ^= x << 13;        x ^= x >> 17;        x ^= x << 5;        self.state = x;        // 归一化到 [0, 1)        (x as f64) / (u32::MAX as f64)    }}fn main() {    let mut handles = vec![];    for i in 0..NUM_THREADS {        handles.push(thread::spawn(move || {            let mut rng = Xorshift::new(i as u32 + 12345);            let mut hits = 0;            for _ in 0..ITERATIONS_PER_THREAD {                let x = rng.next_f64();                let y = rng.next_f64();                if x * x + y * y <= 1.0 {                    hits += 1;                }            }            hits        }));    }    let mut total_hits = 0;    for handle in handles {        total_hits += handle.join().unwrap();    }    let pi = 4.0 * (total_hits as f64) / (TOTAL_ITERATIONS as f64);    println!("Pi: {:.10}", pi);}

4. Go (Goroutines)

Go 的 math/rand 默认是全局锁的,必须使用 rand.New(source) 创建本地 RNG。

package mainimport (    "fmt"    "math/rand"    "sync"    "sync/atomic"    "time")const TOTAL_ITERATIONS = 100_000_000const NUM_WORKERS = 8const ITERATIONS_PER_WORKER = TOTAL_ITERATIONS / NUM_WORKERSfunc main() {    var wg sync.WaitGroup    var totalHits int64    wg.Add(NUM_WORKERS)    for i := 0; i < NUM_WORKERS; i++ {        gofunc(seedOffset int) {            defer wg.Done()            // 每个 Goroutine 必须有自己的 Source,否则会有锁竞争            r := rand.New(rand.NewSource(time.Now().UnixNano() + int64(seedOffset)))            localHits := 0            for j := 0; j < ITERATIONS_PER_WORKER; j++ {                x := r.Float64()                y := r.Float64()                if x*x+y*y <= 1.0 {                    localHits++                }            }            atomic.AddInt64(&totalHits, int64(localHits))        }(i)    }    wg.Wait()    pi := 4.0 * float64(totalHits) / float64(TOTAL_ITERATIONS)    fmt.Printf("Pi: %.10f\n", pi)}

5. Java (Virtual Threads / Thread Pool)

使用 ThreadLocalRandom 以获得最佳多线程随机数性能。

import java.util.ArrayList;import java.util.List;import java.util.concurrent.*;public class Pi {    private static final int TOTAL_ITERATIONS = 100_000_000;    private static final int NUM_THREADS = 8;    private static final int ITERATIONS_PER_THREAD = TOTAL_ITERATIONS / NUM_THREADS;    public static void main(String[] args) throws InterruptedException, ExecutionException {        // 使用 WorkStealingPool (ForkJoinPool)        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);        List<Future<Long>> results = new ArrayList<>();        for (int i = 0; i < NUM_THREADS; i++) {            results.add(executor.submit(() -> {                long hits = 0;                // ThreadLocalRandom 避免了并发竞争                ThreadLocalRandom rng = ThreadLocalRandom.current();                for (int j = 0; j < ITERATIONS_PER_THREAD; j++) {                    double x = rng.nextDouble();                    double y = rng.nextDouble();                    if (x * x + y * y <= 1.0) {                        hits++;                    }                }                return hits;            }));        }        long totalHits = 0;        for (Future<Long> f : results) {            totalHits += f.get();        }        executor.shutdown();        double pi = 4.0 * totalHits / TOTAL_ITERATIONS;        System.out.println("Pi: " + pi);    }}

6. C# (.NET Core)

使用 Parallel.For 配合 threadLocal 状态,这是 C# 处理并行聚合的标准高性能模式。

using System;using System.Threading;using System.Threading.Tasks;const int TOTAL_ITERATIONS = 100_000_000;const int NUM_THREADS = 8;const int ITERATIONS_PER_THREAD = TOTAL_ITERATIONS / NUM_THREADS;long totalHits = 0;Parallel.For(0, NUM_THREADS,    // 本地状态初始化    () => 0L,    // 循环体    (i, loopState, localHits) =>     {        // Random.Shared 在 .NET 6+ 是线程安全的,但在紧密循环中        // 创建本地 Random 实例通常更快,避免内部实现的开销        // 为了极致性能,我们使用 System.Random 实例        var rng = new Random(i * 12345);        for (int j = 0; j < ITERATIONS_PER_THREAD; j++)        {            double x = rng.NextDouble();            double y = rng.NextDouble();            if (x * x + y * y <= 1.0)            {                localHits++;            }        }        return localHits;    },    // 线程结束时的聚合操作    (finalLocalHits) =>     {        Interlocked.Add(ref totalHits, finalLocalHits);    });double pi = 4.0 * totalHits / TOTAL_ITERATIONS;Console.WriteLine($"Pi: {pi}");

配套项目文件:

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>net10.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>  </PropertyGroup></Project>

7. Node.js (Worker Threads)

Node.js 主线程负责分发,Worker 线程计算。

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');const TOTAL_ITERATIONS = 100000000;const NUM_THREADS = 8;const ITERATIONS_PER_THREAD = Math.floor(TOTAL_ITERATIONS / NUM_THREADS);if (isMainThread) {    let completedWorkers = 0;    let totalHits = 0;    for (let i = 0; i < NUM_THREADS; i++) {        const worker = new Worker(__filename, {            workerData: { iterations: ITERATIONS_PER_THREAD }        });        worker.on('message', (hits) => {            totalHits += hits;            completedWorkers++;            if (completedWorkers === NUM_THREADS) {                const pi = 4.0 * totalHits / TOTAL_ITERATIONS;                console.log(`Pi: ${pi}`);            }        });    }} else {    // Worker code    let hits = 0;    const count = workerData.iterations;    for (let i = 0; i < count; i++) {        // Math.random() 在 V8 中对于单个 worker 是足够快的        const x = Math.random();        const y = Math.random();        if (x * x + y * y <= 1.0) {            hits++;        }    }    parentPort.postMessage(hits);}

8. Python (Multiprocessing)

由于 GIL(全局解释器锁)的存在,Python 多线程无法利用多核进行 CPU 计算,必须使用 multiprocessing

import multiprocessingimport randomimport sysTOTAL_ITERATIONS = 100_000_000NUM_PROCESSES = 8ITERATIONS_PER_PROCESS = TOTAL_ITERATIONS // NUM_PROCESSESdef compute_chunk(iterations):    hits = 0    # 局部变量查找比全局快    rand = random.random    for _ in range(iterations):        x = rand()        y = rand()        if x*x + y*y <= 1.0:            hits += 1    return hitsdef main():    with multiprocessing.Pool(processes=NUM_PROCESSES) as pool:        # 分发任务        results = pool.map(compute_chunk, [ITERATIONS_PER_PROCESS] * NUM_PROCESSES)    total_hits = sum(results)    pi = 4.0 * total_hits / TOTAL_ITERATIONS    print(f"Pi: {pi}")if __name__ == '__main__':    main()

9. PHP (PCNTL Fork)

由于 PHP parallel 扩展非标配,这里使用最原生的 pcntl_fork 实现多进程计算,并通过 Pipe 通信。

<?php$total_iterations = 100000000;$num_workers = 8;$iterations_per_worker = (int)($total_iterations / $num_workers);$pids = [];$pipes = [];for ($i = 0; $i < $num_workers; $i++) {    // 创建通信管道 [read, write]    $pair = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);    $pipes[$i] = $pair[0]; // 父进程读端    $pid = pcntl_fork();    if ($pid == -1) {        die("Could not fork worker $i");    } elseif ($pid) {        // 父进程        $pids[$i] = $pid;        fclose($pair[1]); // 关闭父进程中的写端    } else {        // 子进程        fclose($pair[0]); // 关闭子进程中的读端        // 使用 mt_rand (Mersenne Twister) 或 Random\Randomizer (PHP 8.2+)        // mt_rand 在 PHP 中性能尚可        $hits = 0;        $max = mt_getrandmax();        for ($j = 0; $j < $iterations_per_worker; $j++) {            $x = mt_rand() / $max;            $y = mt_rand() / $max;            if (($x*$x + $y*$y) <= 1.0) {                $hits++;            }        }        // 发送结果        fwrite($pair[1], (string)$hits);        fclose($pair[1]);        exit(0);    }}// 汇总结果$total_hits = 0;for ($i = 0; $i < $num_workers; $i++) {    $content = stream_get_contents($pipes[$i]);    $total_hits += (int)$content;    fclose($pipes[$i]);    pcntl_waitpid($pids[$i], $status);}$pi = 4.0 * $total_hits / $total_iterations;echo "Pi: $pi" . PHP_EOL;

6.3 hyperfine 测试结果对比

场景四
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
C
52.0 ± 3.8
44.0
63.9
1.00
Rust
69.0 ± 4.7
62.2
82.6
1.33 ± 0.13
Go
129.6 ± 10.3
107.2
156.8
2.49 ± 0.27
Java
203.3 ± 9.3
187.9
219.0
3.91 ± 0.34
C++
290.6 ± 13.9
278.3
315.4
5.59 ± 0.49
C#
347.4 ± 32.2
324.5
412.9
6.68 ± 0.79
NodeJS
504.3 ± 38.3
468.2
568.1
9.70 ± 1.03
PHP
803.5 ± 79.5
724.6
889.0
15.46 ± 1.91
Python
2163.7 ± 194.2
1973.0
2469.0
41.63 ± 4.84

6.4 结果分析:C 的狂暴与 C++ 的“优雅”代价

1. C (52ms) 与 Rust (69ms):贴地飞行的双子星

C 语言 再次教做人。52ms 完成一亿次计算,意味着它不仅完全吃满了 8 个核心,而且其手写的 xorshift 随机算法几乎没有开销。Rust 紧随其后,仅慢了 17ms。这证明了 Rust 的 std::thread 抽象层极其轻量,且 LLVM 对 Rust 浮点运算的优化与 C 不相上下。

2. C++ (290ms) 的滑铁卢:标准库的“背刺”

这是本场最令人意外的数据:C++ 竟然比 Java 慢,且比 C 慢了 5.5 倍。这并非 C++ 语言本身慢,而是“标准库抽象”的代价。

  • • 在 C 代码中,我们使用了简单的位运算 (xorshift) 直接生成 double。
  • • 在 C++ 代码中,我们使用了 std::uniform_real_distribution。这是一个“数学上更正确”的分布生成器,它为了保证浮点数分布的绝对均匀性,由于内部复杂的逻辑(可能包含拒绝采样),牺牲了吞吐量。
  • • 教训:在高性能计算(HPC)领域,有时候“过于正确”的标准库组件反而是瓶颈。如果把 C++ 换成和 C 一样的裸指针加位运算,它们本该是平手的。

3. Java (203ms) 的逆袭

Java 居然跑赢了 C++ 和 C#!这归功于 JVM 极其成熟的 ThreadLocalRandom 实现。它在多线程下的吞吐量非常惊人,完全没有锁竞争。同时,Java 的 JIT 在热点循环(Hot Loop)中将字节码编译为极其高效的 AVX 指令。对于这种纯粹的数学计算,现代 Java 已经不再是那个笨重的恐龙了。

4. Python (2.1s) 与 PHP (0.8s):沉重的肉身

  • • Python:为了绕过 GIL,我们被迫使用了 multiprocessing。虽然它确实利用了多核,但创建 8 个完整的操作系统进程、序列化数据、进程间通信……这些“行政流程”耗费了大量时间。对于 1 亿次计算这种“短工”来说,启动进程的开销甚至超过了计算本身。
  • • PHP:使用 fork 模式也面临同样的问题。但在 Linux 下,fork() 采用了写时复制(CoW),比 Python 的 spawn 模式稍快一些,因此 PHP 居然比 Python 快了 2.5 倍。

5. Go (130ms):并发是天赋

Go 语言稳坐第三把交椅。Goroutine 的启动成本几乎可以忽略不计,调度器在将计算任务分配给物理线程时表现得丝般顺滑。对于不想折腾 pthread 指针也不想面对 JVM 调优的开发者来说,Go 是并发场景下的甜点区。

7. 场景五:冷启动速度与脚本执行 —— "Hello World" 基准

7.1 唯快不破

在长运行的服务端(Daemon),启动时间可能无关紧要。但在命令行工具(CLI)、AWS Lambda 等无服务器(Serverless)场景下,"冷启动"速度就是用户体验的全部。本场景测试的是程序的最小开销:从操作系统接到执行指令,到加载二进制/解释器,初始化运行时环境,打印字符,最后彻底退出的全过程。

这是一场关于“轻量级”定义的辩论。

7.2 各语言代码实现

设定统一参数:

  • • 任务: 打印 "Hello, World!" 并立即退出。
  • • 目的: 测量程序从操作系统 exec() 到完全退出的最小时间(Runtime Overhead)。

1. C (GCC)

#include <stdio.h>int main() {    printf("Hello, World!\n");    return 0;}

2. C++ (G++)

#include <iostream>int main(){    std::cout << "Hello, World!" << std::endl;    return 0;}

3. Rust

fn main() {    println!("Hello, World!");}

4. Go

package mainimport "fmt"func main() {    fmt.Println("Hello, World!")}

5. ASM (NASM x64)

这是本测试的绝对基准。不链接 C 标准库,直接发起 Syscall,生成的二进制文件极小,启动速度代表了 Linux 内核加载 ELF 文件的极限。

; 直接使用 Linux Syscalls (Write, Exit); 无 libc 依赖global _startsection .data    msg db "Hello, World!", 10  ; 10 = \n    len equ $ - msgsection .text_start:    ; sys_write(1, msg, len)    mov rax, 1       ; syscall number for sys_write    mov rdi, 1       ; file descriptor 1 (stdout)    mov rsi, msg     ; pointer to buffer    mov rdx, len     ; buffer length    syscall    ; sys_exit(0)    mov rax, 60      ; syscall number for sys_exit    xor rdi, rdi     ; exit code 0    syscall

6. Java

测试 JVM 的冷启动开销(类加载、JIT 初始化等)。

public class Hello {    public static void main(String[] args) {        System.out.println("Hello, World!");    }}

7. C# (.NET Core)

测试 CLR 的冷启动开销。

using System;Console.WriteLine("Hello, World!");

配套项目文件:

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <OutputType>Exe</OutputType>    <TargetFramework>net10.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>    <!-- 对于 Hello World,开启 AOT 可以大幅缩短启动时间,         但为了展示普通 .NET 应用的基准,此处暂不开启 PublishAot -->  </PropertyGroup></Project>

8. Node.js (JavaScript)

测试 V8 引擎和 Node 运行时环境的初始化时间。

console.log("Hello, World!");

9. Python

测试 CPython 解释器的启动开销。

print("Hello, World!")

10. PHP

测试 PHP CLI 模式的启动开销。

<?phpecho "Hello, World!" . PHP_EOL;

7.3 hyperfine 测试结果对比

场景五
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
ASM
0.3 ± 0.3
0.0
3.1
1.00
C
0.6 ± 0.2
0.3
1.7
2.18 ± 2.11
Rust
0.9 ± 0.3
0.4
3.7
3.18 ± 3.13
C++
1.3 ± 0.3
0.8
3.0
4.74 ± 4.47
Go
1.6 ± 0.3
1.0
3.6
5.72 ± 5.37
Python
11.9 ± 0.9
10.3
15.0
42.04 ± 38.69
PHP
15.9 ± 1.7
13.2
28.3
56.10 ± 51.82
NodeJS
26.7 ± 3.6
21.2
38.2
94.11 ± 87.26
Java
28.0 ± 1.8
24.1
32.3
98.62 ± 90.71
C#
34.5 ± 3.5
29.3
52.4
121.66 ± 112.31

7.4 结果分析:眨眼之间的战争

1. 汇编 (ASM):快到不存在

0.3 ms这是什么概念?人类眨一次眼需要 300ms。在这一眨眼的功夫里,汇编程序已经可以启动并退出 1000 次这个时间基本上等于 Linux 内核 execve 系统调用的物理极限。它告诉我们:如果你追求极致的瞬时响应,没有任何中间商(Runtime)能赚差价。

2. 本地编译组 (C/Rust/Go):毫秒级的差别

C、Rust 和 Go 都控制在 2ms 以内。

  • • Go (1.6ms):虽然 Go 打包了垃圾回收器和协程调度器,但 Google 显然对它的启动过程做了外科手术般的优化。它比 C 慢的那 1ms,是你享受自动内存管理的入场券——这绝对物超所值。

3. 脚本语言的胜利:Python 与 PHP

意不意外?Python (12ms) 和 PHP (16ms) 竟然完爆了 Java 和 Node.js。

  • • 我们常嘲笑 Python 慢,但在“启动”这件事上,CPython 解释器其实非常轻量。它不需要像 JVM 那样去申请大块堆内存、预热 JIT 编译器、加载庞大的类库。它只是读取文件、解析、运行。
  • • 这就是为什么 Python 和 PHP 依然统治着运维脚本和短生命周期 Web 请求(CGI 模式)的领域。

4. 巨型运行时的“起床气”:Java、C#、Node.js

排在队尾的是 Java (28ms)、C# (34.5ms) 和 Node.js (26.7ms)。

  • • 这就是“工业级”的代价。当你输入 java Hello 时,JVM 就像是一个要在周末出门旅行的人:先找箱子(申请内存),再把衣服折叠好(加载核心类库),检查煤气水电(初始化 GC 和 JIT 线程),最后才迈出门说一句 "Hello"。
  • • 虽然它们比 ASM 慢了 100 倍,但客观地说,2026 年的 Java 25 和 .NET 10 已经比十年前快了太多(以前可是 100ms 起步)。但在编写 lscat 这种瞬间完成的小工具时,还是别用它们了,用户会感觉到那极其微妙的“卡顿”。

8. 综合数据可视化与排名

数据不会说谎,但数据会让人汗流浃背。

在经历了五个场景的残酷角斗后,我们收集了数千次运行的数据。现在,是时候把这些散落的数字汇聚成图表,看看谁是六边形战士,谁是偏科天才,而谁又是来“凑数”的。

8.1 CPU 综合性能天梯图

这张图表汇集了质数筛选、斐波那契递归和并发 Pi 计算三个硬核场景。为了不让 Python 的柱子冲出屏幕并捅破你的显示器,我们不得不使用了 对数坐标 (Log Scale)

  • • T0 梯队 (神之领域)C / C++ / Rust / ASM这四位选手基本住在 X 轴的零点附近。它们之间的差距在毫秒级,胜负往往取决于编译器当天的心情(内联策略)或者你是否多写了一个 const
  • • T1 梯队 (凡人巅峰)GoGo 就像是一个穿着西装跑步的运动员,虽然带着 GC 的领带,但依然跑得飞快。它在并发场景下甚至能摸到 T0 的脚后跟。
  • • T2 梯队 (工业重机)Java / C#启动慢、预热慢,但一旦跑起来,它们就是一辆重型坦克。在长运行任务中,它们与 C++ 的差距通常在 2-3 倍以内,考虑到开发效率,这完全可以接受。
  • • T3 梯队 (脚本组)Node.js / PHP / Python这里的差距是断崖式的。Node.js 尚能看到前面的车尾灯,而 Python 在纯计算领域,基本上是在用“地质年代”来计时的。

8.2 内存占用效率对比

虽然 Hyperfine 主要关注时间,但我们在测试过程中通过 time -v 偷偷观察了各选手的内存条(RSS)。

  • • 极致扣门奖ASM / C / Rust在 Hello World 中,它们只吃了几百 KB。即便在处理 1GB 文件时,它们也能通过缓冲区控制,精准地只占用 64MB 左右的内存。它们对内存的控制欲简直到了“强迫症”的地步。
  • • 挥金如土奖Java / C#“什么?你只打印一行字?稍等,先给我来 30MB 内存润润喉。”JVM 和 CLR 的启动开销是固定的,这使得它们在微服务或 CLI 工具场景下显得有些“富贵病”。但在大内存场景下,它们的 GC 吞吐能力又是无可替代的。
  • • 薛定谔的内存Node.js / Python动态语言的对象头(Object Header)开销巨大。一个简单的整数在 Python 中可能需要 28 字节。在场景二(递归)中,Python 的内存消耗甚至超过了 Java,因为它为每一层递归都创建了完整的栈帧对象。

8.3 开发效率 vs 运行效率 (Trade-off)

如果把“代码行数”作为开发成本,把“运行时间”作为收益,我们得到了一张残酷的性价比图。

性价比图
  • • C / ASM:拿阳寿换性能。你写了一下午,只为了优化掉 10ms。每写一行代码,都需要小心翼翼地祈祷不要 Segfault。
    • • 适合场景: 操作系统内核、驱动、嵌入式、高频交易。
  • • Rust / C++:陡峭的学习曲线,极致的回报。Rust 编译器像是一个严厉的教导主任,在你代码编译通过之前就会把你骂哭。但一旦通过,它跑得既快又安全。
    • • 适合场景: 游戏引擎、浏览器内核、底层基础设施。
  • • Go / Java / C#:成年人的最佳选择。它们不追求极致的快,也不追求极致的短。它们在“写得快”和“跑得快”之间找到了一个黄金平衡点。
    • • 适合场景: 几乎所有的企业级后端服务。
  • • Python / JS / PHP:虽然我跑得慢,但我上线快啊。C++ 程序员还在写 Makefile 的时候,Python 程序员已经把 MVP(最小可行性产品)上线并拿到融资了。
    • • 适合场景: 胶水代码、Web 全栈、数据科学(作为 C++ 的调用器)、原型开发。

8.4 语言特性总结:众神归位

各语言表现雷达图

最后,让我们根据本次角斗场表现,给各位选手颁发终极评语:

ASM / C / C++:基石三巨头

"性能是底线,头发是代价。"它们是计算机世界的物理定律。无论上层语言多么花哨,扒开皮看到底,最后都是 C 在负重前行。极致的性能意味着你需要手动管理每一粒沙子(内存),适合那些控制欲极强且不惧怕指针的勇士。

Rust:新时代的守门人

"安全,而且快。编译器比你更懂你的代码。"Rust 证明了内存安全和零成本抽象不是悖论。它正在以肉眼可见的速度侵蚀 C++ 的领地。唯一的缺点?你可能需要先和 Borrow Checker 打一架。

Go:云原生的亲儿子

"少即是多,并发即正义。"Go 在并发场景下的表现令人印象深刻。它没有花哨的语法糖,只有简单粗暴的 Goroutine。如果你想写一个能抗住高并发的网络服务,选它准没错。

Java / C#:企业级航母

"稳重,大气,除了启动慢点没毛病。"JIT 技术已经非常成熟,在热点代码上甚至能反超静态编译语言。它们拥有最庞大的生态系统,虽然显得有些臃肿,但绝对靠谱。

Python / Node.js / PHP:灵活的游侠

"生命苦短,我用脚本。"不要因为它们在 CPU 榜单垫底就嘲笑它们。在 I/O 密集场景(如 Web 服务)中,PHP 和 Node.js 的表现极具竞争力。而 Python,虽然本体慢,但它成功地把所有脏活累活都外包给了 C/C++(NumPy, PyTorch),从而统治了 AI 世界。这是一个关于“领导力”的励志故事。

9. 结语:诸神黄昏之后

角斗场的尘埃落定,十位选手有的毫发无伤,有的气喘吁吁,有的……还在等待操作系统回收它的内存。

在看完所有硬核数据后,你可能会问:“所以,到底谁才是最好的语言?”很遗憾,软件工程领域没有银弹,只有取舍(Trade-off)。但如果你非要一个答案,我们可以根据你的“痛苦偏好”来颁奖。

9.1 谁是赢家?(颁奖典礼)

🏆 极限性能奖:C / C++ / Rust

  • • 推荐场景:操作系统内核、嵌入式设备、3A 游戏引擎、高频交易系统、视频编解码。
  • • 颁奖词:如果你认为 1ms 的延迟是不可接受的,或者你的程序需要运行在只有 128KB 内存的微波炉上,选它们。
    • • C/C++:献给那些相信自己比编译器聪明,且不介意偶尔调试内存泄漏到深夜的硬汉。
    • • Rust:献给那些既想要 C++ 的速度,又想保住自己头发(和饭碗)的现代极客。

🏆 工业霸主奖:Java / Go / C#

  • • 推荐场景:高并发网络服务、大型微服务架构、企业级后台、金融业务系统。
  • • 颁奖词:成年人的世界不只有速度,还有稳定性、可维护性和招聘难度。
    • • Go:当你想在一周内写出一个能抗住 10 万并发的服务时,Go 是上帝送来的礼物。
    • • Java / C#:当你的团队有 500 人,且需要代码在 10 年后依然能跑时,请拥抱这些重型装甲车。

🏆 开发体验奖:Python / Node.js / PHP

  • • 推荐场景:Web 全栈开发、数据分析、AI 训练(胶水层)、快速原型验证、运维脚本。
  • • 颁奖词:生命苦短,我不想手动管理内存。
    • • Python:虽然慢,但它背后站着 C/C++ 写好的几万个库。你只管调包,剩下的交给摩尔定律。
    • • PHP:别笑,在这个世界上 80% 的网站不仅还在用 PHP,而且跑得挺欢。它是“简单粗暴有效”的代名词。
    • • Node.js:I/O 密集型应用的神器,也是前端工程师统治世界的权杖。

9.2 性能不是唯一指标:给数据泼点冷水

在本次评测中,Python 在计算 Fibonacci 时比 C++ 慢了 66 倍。这是否意味着 Python 是垃圾?

绝对不是。

在现实世界的软件开发中,Raw Performance(裸机性能) 往往不是瓶颈。

  1. 1. I/O 才是瓶颈:你的 Web 服务慢,通常是因为数据库查询慢,或者是网络延迟高,而不是因为你的 for 循环多跑了 2ms。在这些场景下,Python 和 Go 的端到端响应时间差距可能只有 10%。
  2. 2. 开发成本才是大头:服务器很便宜,程序员很贵。如果用 Python 开发一个功能需要 1 天,用 C++ 需要 1 周。在业务快速迭代的初期,选择 Python 节省下来的人力成本,足够你买一屋子最新的服务器来弥补性能差距。
  3. 3. 生态决定生死:你想做 AI?Python 是唯一的选择,性能再差你也得用,因为所有轮子都在这。你想做高性能 Web?Node.js 的 npm 生态大到让你害怕。

结论:脱离场景谈性能,就是耍流氓。

9.3 附录:复现与源码

为了保证本次评测的透明度,所有测试代码、构建脚本 (Makefile) 以及可视化工具均已开源。如果你对结果有异议,或者想看看你的机器能不能跑出不同的结果,欢迎 Fork 并发起挑战。

  • • GitHub 仓库地址https://github.com/mlikaler/The-Ultimate-Performance-Arena.git

最后的忠告无论你选择哪种语言,请记住:最慢的永远不是语言,而是写出  循环的那个程序员。


(全文完)

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-08 14:13:52 HTTP/2.0 GET : https://f.mffb.com.cn/a/463447.html
  2. 运行时间 : 0.095044s [ 吞吐率:10.52req/s ] 内存消耗:5,013.23kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f2a3bf88e6862497984a6e787e3804ff
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000594s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000894s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000294s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000291s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000525s ]
  6. SELECT * FROM `set` [ RunTime:0.000195s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000670s ]
  8. SELECT * FROM `article` WHERE `id` = 463447 LIMIT 1 [ RunTime:0.000723s ]
  9. UPDATE `article` SET `lasttime` = 1770531232 WHERE `id` = 463447 [ RunTime:0.011805s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000369s ]
  11. SELECT * FROM `article` WHERE `id` < 463447 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000489s ]
  12. SELECT * FROM `article` WHERE `id` > 463447 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000381s ]
  13. SELECT * FROM `article` WHERE `id` < 463447 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000724s ]
  14. SELECT * FROM `article` WHERE `id` < 463447 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001139s ]
  15. SELECT * FROM `article` WHERE `id` < 463447 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001349s ]
0.096730s