一、文件準備
樣本內容,N行9列的csv標準格式,有字符串,有浮點數,有整型。
有兩個csv文件,一個大約是2.1萬行;一個是64萬行。
二、toml文件
[package]
name = "my_duckdb"
version = "0.1.0"
edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
duckdb = { version = "0.10.2", features = ["bundled"] }
polars = {version ="0.39.0"}
三、main.rs
use duckdb::{arrow::{record_batch::RecordBatch, util::pretty::print_batches},Connection, Result,
};
use polars::prelude::*;
use std::time::{Instant};
fn main() {//test.csv:2w行;test2.csv:64w行let csvs = ["test.csv","test2.csv"]; for csv in csvs{duckdb_read_csv(csv).unwrap();polars_read_csv(csv);}}
fn duckdb_read_csv(filepath:&str) ->Result<()> {let duckdb_csv_time = Instant::now();let db = Connection::open_in_memory()?;let sql_format = format!("SELECT * from read_csv('{}');",filepath);let rbs: Vec<RecordBatch> = db.prepare(&sql_format)?.query_arrow([])?.collect();//print_batches(&rbs).unwrap();// 批量打印assert!(rbs.len()>0);println!("duckdb取出的行數:{:?} 列數:{:?}",rbs[0].num_rows(),rbs[0].num_columns());println!("duckdb 讀csv花時: {:?} 秒!", duckdb_csv_time.elapsed().as_secs_f32());let _ = db.close();Ok(())
}fn polars_read_csv(filepath:&str){let polars_csv_time = Instant::now();let df = CsvReader::from_path(filepath).unwrap().has_header(true).finish().unwrap();println!("polars讀出csv的行和列數:{:?}",df.shape());println!("polars 讀csv 花時: {:?} 秒!", polars_csv_time.elapsed().as_secs_f32());
}
四、輸出
-----------"test.csv"-------------
duckdb取出的行數:2048 列數:9
duckdb 讀csv花時: 0.032244585 秒!
polars讀出csv的行和列數:(21357, 9)
polars 讀csv 花時: 0.006511025 秒!
-----------"test.csv"-------------
-----------"test2.csv"-------------
duckdb取出的行數:2048 列數:9
duckdb 讀csv花時: 0.1279175 秒!
polars讀出csv的行和列數:(640710, 9)
polars 讀csv 花時: 0.02369589 秒!
-----------"test2.csv"-------------
duckdb和polars讀文件共花:0.19441628秒!
結論:從上面的樣本來看,分別用duckdb和polars來讀csv兩個不同大小的文件,polars有優勢。當然,也可能是duckdb庫封裝的問題,也可能是文件大小不同,測試代表性還不全。謹供參考!
五、問題
從輸出可以明顯看出,duckdb庫讀出來的num_rows是有問題的。這個問題還待查實。從print_batches(&rbs).unwrap(),打印出來的內容來看,并沒有少。