You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python文件读写性能远超Dart?附测试数据与代码

Python与Dart文件读写性能测试差异分析

我在同一Mac系统下对Python和Dart的文件读写性能做了对比测试,代码结构保持相似以保证公平性,但结果超出预期:Python的文件IO速度显著快于Dart。具体耗时数据如下:

测试耗时数据

Python

  • 写入耗时:10.28秒
  • 读取耗时:4.88秒
  • 总耗时:15.16秒

Dart

  • 写入耗时:79秒
  • 读取耗时:10秒
  • 总耗时:90秒

原本预期Dart的表现至少与Python相当,甚至更优,因此对这一结果存在困惑,希望解答以下问题:

  1. Python与Dart在文件处理性能上存在显著差异的已知原因有哪些?
  2. Python或Dart中的特定库、编码格式或其他系统级因素是否会影响文件IO速度?
  3. 有哪些优化技术可以提升Dart的文件读写性能?

问题解答

1. 性能差异的已知原因

  • 底层IO实现差异:Python的open()直接封装了操作系统的标准C库IO函数,这些函数经过长期优化,默认启用了高效的大尺寸用户态缓冲区策略。而Dart的同步文件IO(writeStringSync/readSync)在字符串处理上额外增加了编码转换开销,且默认缓冲区配置更保守。
  • 字符串处理机制不同:Python文本模式下写入字符串时,若编码匹配系统默认(Mac为UTF-8),可直接按字节流写入;Dart的writeStringSync每次调用都会将字符串转换为UTF-8字节序列,循环执行时会累积大量编码开销。
  • 同步IO调度差异:Dart VM处理同步阻塞IO时,可能存在额外的线程调度或上下文切换开销;Python的CPython在同步IO时直接阻塞当前线程,更贴近操作系统原生调度逻辑。

2. 影响文件IO速度的因素

  • 库与API选择:Python的open()默认使用缓冲IO,效率更高;Dart若循环调用writeStringSync,远不如单次写入大字符串高效,且dart:io对同步IO的优化不如异步IO充分。
  • 编码格式:测试中的纯ASCII字符串,Python可直接按字节写入无需转换;Dart仍会执行UTF-8编码步骤,额外消耗资源。
  • 系统级因素:Mac的文件系统缓存策略、磁盘IO调度、进程优先级都会影响性能;Dart VM的启动预热时间在短测试中被放大,而Python的启动预热更轻量。

3. Dart文件读写性能优化方案

  • 预转换字符串为字节数组:提前将字符串转成字节数组,循环写入字节而非字符串,避免重复编码开销:
    final blockBytes = utf8.encode(blockSize);
    // 写入时使用sink.writeFromSync(blockBytes)
    
  • 增大读取缓冲区:将readSync(1024)改为更大的缓冲区(如64 * 1024或1024 * 1024),减少系统调用次数。
  • 改用异步IO:Dart的异步IO(openWrite/openRead)经过更充分优化,能更好利用系统资源,大文件操作优势明显:
    final sink = file.openWrite();
    for (int i = 0; i < cnt; i++) {
      await sink.write(blockSize);
    }
    await sink.close();
    
  • 单次写入/读取大内容:若允许,将所有内容拼接后单次写入(如file.writeAsStringSync(blockSize * cnt)),减少循环带来的调用开销。
  • 手动指定缓冲区大小:通过openSync的bufferSize参数设置更大的缓冲区:
    final sink = file.openSync(mode: FileMode.write, bufferSize: 1024 * 1024);
    

测试代码

Python代码

import time
import os

def benchmark(cnt=200):
    block_size = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" * (1024 * 1024)
    file_path = "large_benchmark_test.txt"

    start_time = time.time()
    with open(file_path, "w") as file:
        for _ in range(cnt):
            file.write(block_size)
    write_end_time = time.time()

    with open(file_path, "r") as file:
        while file.read(1024):
            pass
    read_end_time = time.time()

    write_time = write_end_time - start_time
    read_time = read_end_time - write_end_time
    total_time = read_end_time - start_time

    print(f"Python - Write: {write_time:.2f} s")
    print(f"Python - Read: {read_time:.2f} s")
    print(f"Python - Total: {total_time:.2f} s")
    os.remove(file_path)

Dart代码

import 'dart:io';
import 'dart:convert';

void benchmark({int cnt=200}) {
  final blockSize = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' * 1024 * 1024;
  final filePath = 'large_benchmark_test.txt';
  final file = File(filePath);

  final writeStartTime = DateTime.now();
  final sink = file.openSync(mode: FileMode.write);
  for (int i = 0; i < cnt; i++) {
    sink.writeStringSync(blockSize);
  }
  sink.closeSync();
  final writeEndTime = DateTime.now();
  final writeTime = writeEndTime.difference(writeStartTime).inSeconds;
  print("Dart (Synch) - Write: $writeTime s");
  
  final readStartTime = DateTime.now();
  final reader = file.openSync(mode: FileMode.read);
  while (true) {
    final buffer = reader.readSync(1024);
    if (buffer.isEmpty) break;
  }
  reader.closeSync();
  final readEndTime = DateTime.now();

  final readTime = readEndTime.difference(readStartTime).inSeconds;
  final totalTime = readEndTime.difference(writeStartTime).inSeconds;

  print("Dart (Synch) - Read: $readTime s");
  print("Dart (Synch) - Total: $totalTime s");
  file.deleteSync();
}

内容的提问来源于stack exchange,提问作者Don Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:28:13