您可能看到的是基准测试中的一个常见问题:the caching of files by your operating system.如果内存量允许,大多数现代操作系统都会try 缓存访问的文件.
第一次访问该文件时,您的操作系统可能会将1.51 GB的文件缓存在RAM中(甚至可能在您创建该文件时).因此,后续的检索并不是真正访问硬盘——它们是针对RAM中的缓存文件运行的,这一过程比从硬盘读取要快得多.(这是在RAM中缓存文件的一种方式.)
An Example
例如,我创建了一个29.9 GB的csv文件,并有意将其放置在我的NAS(网络连接存储)上,而不是本地硬盘上.作为参考,我的NAS和我的机器通过10千兆/秒的网络连接.
第一次运行这个基准测试代码大约需要54秒.
import polars as pl
import time
start = time.perf_counter()
(
pl.scan_csv('/mnt/bak-projects/StackOverflow/benchmark.csv')
.filter(pl.col('col_0') == 100)
.collect()
)
print(time.perf_counter() - start)
shape: (1, 27)
┌─────┬───────┬───────┬───────┬─────┬────────┬────────┬────────┬────────┐
│ id ┆ col_0 ┆ col_1 ┆ col_2 ┆ ... ┆ col_22 ┆ col_23 ┆ col_24 ┆ col_25 │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═══════╪═══════╪═══════╪═════╪════════╪════════╪════════╪════════╡
│ 1.0 ┆ 100 ┆ 100 ┆ 100 ┆ ... ┆ 100 ┆ 100 ┆ 100 ┆ 100 │
└─────┴───────┴───────┴───────┴─────┴────────┴────────┴────────┴────────┘
>>> print(time.perf_counter() - start)
53.92608916899917
因此,在54秒内读取一个29.9 GB的文件大约是29.9 GB*(每字节8位)/54秒=4.4 GB/秒.从网络驱动器检索文件不错.当然,在我的万兆/秒网络上是可能的.
然而,文件现在被我的操作系统(Linux)缓存在RAM中(我有512 GB的RAM).因此,当我第二次运行相同的基准测试代码时,只花了3.5秒:
shape: (1, 27)
┌─────┬───────┬───────┬───────┬─────┬────────┬────────┬────────┬────────┐
│ id ┆ col_0 ┆ col_1 ┆ col_2 ┆ ... ┆ col_22 ┆ col_23 ┆ col_24 ┆ col_25 │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═══════╪═══════╪═══════╪═════╪════════╪════════╪════════╪════════╡
│ 1.0 ┆ 100 ┆ 100 ┆ 100 ┆ ... ┆ 100 ┆ 100 ┆ 100 ┆ 100 │
└─────┴───────┴───────┴───────┴─────┴────────┴────────┴────────┴────────┘
>>> print(time.perf_counter() - start)
3.5459880090020306
如果我的29.9 GB文件真的在网络上传输,这意味着网络速度至少为29.9*8/3.5秒=68 GB/s.(显然,在我的万兆/秒网络上是不可能的.)
第三次:2.9秒
shape: (1, 27)
┌─────┬───────┬───────┬───────┬─────┬────────┬────────┬────────┬────────┐
│ id ┆ col_0 ┆ col_1 ┆ col_2 ┆ ... ┆ col_22 ┆ col_23 ┆ col_24 ┆ col_25 │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═══════╪═══════╪═══════╪═════╪════════╪════════╪════════╪════════╡
│ 1.0 ┆ 100 ┆ 100 ┆ 100 ┆ ... ┆ 100 ┆ 100 ┆ 100 ┆ 100 │
└─────┴───────┴───────┴───────┴─────┴────────┴────────┴────────┴────────┘
>>> print(time.perf_counter() - start)
2.8593162479992316
根据您的操作系统,有一种方法可以在基准测试之前从RAM中刷新缓存文件.