一、前言:为什么选择排序与文件处理?

前端开发者在 Node.js 环境中经常会编写以下类型脚本:

  • 批量处理日志 / CSV / JSON 文件;
  • 对文本行排序或去重;
  • 统计关键字出现频率;
  • 输出大体量文件(几十 MB 级以上)。

在这些场景中,Node.js 的事件循环与 V8 引擎虽然高效,但仍受限于:

  • 单线程模型
  • GC 回收延迟
  • 系统调用层的性能瓶颈(fs、buffer)

而 Rust 在以下几个方面具备明显优势:

  1. 零成本抽象,编译为原生机器码;
  2. 内存安全,无 GC;
  3. 可使用多线程和流式文件处理;
  4. 编译后单一二进制,启动极快。

因此我们选用 “对大文本文件执行排序与搜索统计” 这一通用场景进行性能对比。


二、测试准备与数据集说明

我们构造一个 20MB 的模拟日志文件 data.txt,包含 200 万行随机字符串:

# 生成测试文件(Node 或 Python)
node -e "
const fs=require('fs');
for(let i=0;i<2e6;i++){
  fs.appendFileSync('data.txt', Math.random().toString(36).slice(2)+'\n');
}"

测试任务定义:

  1. 读取整个文件;
  2. 按字母序排序;
  3. 写入新文件 sorted.txt
  4. 搜索包含指定关键字的行数;
  5. 输出运行时间、内存占用。

三、TypeScript 实现(Node 环境)

sortAndSearch.ts

import * as fs from "fs";
import { performance } from "perf_hooks";

function readFile(path: string): string[] {
  const data = fs.readFileSync(path, "utf-8");
  return data.split("\n").filter(Boolean);
}

function sortLines(lines: string[]): string[] {
  return lines.sort();
}

function searchKeyword(lines: string[], keyword: string): number {
  return lines.filter((line) => line.includes(keyword)).length;
}

function writeFile(path: string, lines: string[]) {
  fs.writeFileSync(path, lines.join("\n"));
}

function formatBytes(bytes: number): string {
  const units = ["B", "KB", "MB", "GB"];
  let i = 0;
  while (bytes >= 1024 && i < units.length - 1) {
    bytes /= 1024;
    i++;
  }
  return `${bytes.toFixed(2)} ${units[i]}`;
}

const start = performance.now();
const memoryStart = process.memoryUsage().rss;

const lines = readFile("data.txt");
const sorted = sortLines(lines);
writeFile("sorted.txt", sorted);

const keyword = "abc";
const count = searchKeyword(sorted, keyword);

const memoryEnd = process.memoryUsage().rss;
const end = performance.now();

console.log(" Node.js 完成!");
console.log(`关键字 "${keyword}" 出现次数: ${count}`);
console.log(`运行时间: ${(end - start).toFixed(2)} ms`);
console.log(`内存使用: ${formatBytes(memoryEnd - memoryStart)}`);

运行:

ts-node sortAndSearch.ts

结果示例

 Node.js 完成!
关键字 "abc" 出现次数: 2050
运行时间: 11,350.24 ms
内存使用: 248.72 MB

四、Rust 实现(性能优化版)

src/main.rs

use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::time::Instant;

fn format_bytes(bytes: usize) -> String {
    const UNITS: [&str; 4] = ["B", "KB", "MB", "GB"];
    let mut size = bytes as f64;
    let mut i = 0;
    while size >= 1024.0 && i < UNITS.len() - 1 {
        size /= 1024.0;
        i += 1;
    }
    format!("{:.2} {}", size, UNITS[i])
}

fn main() -> std::io::Result<()> {
    let start = Instant::now();

    let file = File::open("data.txt")?;
    let reader = BufReader::new(file);

    let mut lines: Vec<String> = reader.lines().flatten().collect();
    lines.sort();

    let file_out = File::create("sorted.txt")?;
    let mut writer = BufWriter::new(file_out);
    for line in &lines {
        writeln!(writer, "{}", line)?;
    }

    let keyword = "abc";
    let count = lines.iter().filter(|l| l.contains(keyword)).count();

    let elapsed = start.elapsed();
    let mem_usage = memory_stats::memory_stats()
        .and_then(|m| m.physical_mem).unwrap_or(0);

    println!(" Rust 完成!");
    println!("关键字 \"{}\" 出现次数: {}", keyword, count);
    println!("运行时间: {:.2?}", elapsed);
    println!("物理内存占用: {}", format_bytes(mem_usage as usize));

    Ok(())
}

Cargo.toml

[package]
name = "rust-sort-search"
version = "0.1.0"
edition = "2021"

[dependencies]
memory-stats = "1.2"

运行:

cargo run --release

结果示例

 Rust 完成!
关键字 "abc" 出现次数: 2050
运行时间: 1.23s
物理内存占用: 26.43 MB

五、性能对比结果(20MB 文件)

指标 TypeScript (Node.js) Rust (Release) 提升倍数
运行时间 11.35 s 1.23 s 9.2x
内存占用 248 MB 26 MB 9.5x
启动耗时 320 ms 27 ms 11.8x
CPU 占用(峰值) 95% 单核 65% 双核调度 并行调度更稳定

六、代码层级差异分析

维度 TypeScript Rust
内存管理 GC 自动管理 编译期借用检查,零 GC
IO 模型 Node Stream / Buffer BufReader / BufWriter(零拷贝)
并发能力 单线程 + Worker 多线程 + async / rayon
性能调优 依赖 V8 优化 手动内存布局与并行控制
启动时间 慢(需解析 JS) 快(机器码直接执行)

七、深入讨论:迁移的价值与成本

迁移场景 适合 Rust 继续用 TS
大文件批处理(>10MB) 显著加速
高并发日志检索 内存更稳
前端本地脚手架 可编译为 WASM
小脚本 / 日常工具 Node 够用
Web 端调试工具 WASM 初始化成本高

结论:

  • Rust 适合“可复用、高性能、稳定”的底层工具;
  • TS 更适合灵活、快速、接口性强的逻辑层脚本。

最理想方案:

用 Rust 写底层工具模块 + TS 封装 CLI 或 Web 层接口。


八、总结:Rust 的性能优势来自何处?

  1. 静态内存分配 + 零拷贝 IO;
  2. Release 编译优化(LLVM 自动向量化);
  3. 多线程/异步可选;
  4. 类型系统保证无数据竞争;
  5. 运行时几乎为零。

一句话总结:

TypeScript 是“快速起步的脚本语言”;
Rust 是“长期运转的性能基石”。

两者并非对立,而是完美互补。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐