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

为何Rust读取TSV文件性能不及Python?求问题排查

TSV文件处理:Rust实现性能不如Python的疑问

我有一个TSV文件,其中有多行以#开头的注释行。文件包含多列,但我只需要第0列和第2列,且这两列存在重复数据,需要尽量去重。

Python实现及性能

实现该功能的Python函数如下,经timeit测试执行时间为1.74s:

def read_faulty_tsv(path):
    # 1.74 s ± 18.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    with open(path) as _f:
        i = 0
        header = None
        for line in _f.readlines():
            if line.startswith("#"):
                i += 1
            else:
                break

    data = pd.read_csv(path, sep="\t", skiprows=i, header=None)
    data = data.drop_duplicates([0,2])
    return data

注:第0列和第2列存在关联(如第0列是X,第2列是2X),因此可优化为仅按第0列去重,优化后性能基本不变(约1.86s)。

Rust实现及性能

我用Rust实现了两个类似功能的函数:一个使用原生方法,另一个使用csv crate(版本1.1)。未开启--release时,两个函数分别耗时5.260s和7.729s,远慢于Python;开启--release后,耗时降至2.486s和3.971s,但仍比Python慢。

使用csv crate的实现

use csv::ReaderBuilder;
use std::time::Instant;
use std::io::{BufRead, BufReader};
use std::fs::File;
use std::error::Error;
use std::collections::{HashSet,HashMap};
use std::path::PathBuf;

fn read_fault_tsv(file_path:&PathBuf)->Result<HashMap<u32,u32>, Box<dyn Error>>{
    
    let mut final_labels: HashMap<u32, u32> = HashMap::new();
    
    let file = File::open(file_path)?;
    let reader = BufReader::new(file);
    // Create a vector to store non-comment lines
    let mut lines = Vec::new();

    let start_time = Instant::now();
    // Read lines and skip comment lines
    for line in reader.lines() {
        let line = line?;
        if !line.starts_with('#') {
            lines.push(line);
        }
    }
    let joined_lines = lines.join("\n");
    // Create a CSV reader with tab delimiter from the collected lines
    let mut rdr = ReaderBuilder::new()
        .delimiter(b'\t')
        .from_reader(joined_lines.as_bytes());
    for result in rdr.records(){
        match result {
            Ok(record)=>{
                let first_c = record[0].parse::<u32>().unwrap();
               if !final_labels.contains_key(&first_c){
                let third_c = record[0].parse::<u32>().unwrap();
                final_labels.insert(first_c,third_c);
                }
        }
            Err(e) => {
                eprintln!("Error -- {}",e)
            }
        }
    }
    let elapsed_time = start_time.elapsed();
    println!("Elapsed time: {}.{:03} seconds", elapsed_time.as_secs(), elapsed_time.subsec_millis());
    Ok(final_labels)
    
}

原生方法实现

fn read_fault_tsv2(file_path:&PathBuf)->Result<HashMap<u32,u32>, Box<dyn Error>>{
    let mut final_labels: HashMap<u32, u32> = HashMap::new();

    let file = File::open(file_path)?;
    let reader = BufReader::new(file);

    let lines = reader.lines()
    .filter_map(Result::ok)
    .filter(|line|!line.starts_with('#'));
    let start_time = Instant::now();
    for line in lines{
        let columns: Vec<&str> = line.split('\t').collect();
        if columns.len() > 2 {
            if let Ok(key) = columns[0].parse::<u32>() {
                if !final_labels.contains_key(&key) {
                    if let Ok(value) = columns[2].parse::<u32>() {
                        final_labels.insert(key, value);
                    }
                }
            }
        }

    };
    let elapsed_time = start_time.elapsed();
    println!("Elapsed time: {}.{:03} seconds", elapsed_time.as_secs(), elapsed_time.subsec_millis());
    
    Ok(final_labels)
}

疑问

请问我是否在实现中存在严重问题,导致Python性能超过Rust?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:34:58