在我的代码中,我有一个文件数据库httpcache.db
,我的应用程序可以通过单个读/写FILE I / O api调用将其读入内存并将其写回到磁盘。我使用普通的fopen / fread对其进行读写。我决定压缩它,看看尺寸的减小是否会导致整体速度的提高。首先,我测量了读取httpcache.db
所需的加载时间,并且获得了350微秒的相当稳定的时间。 httpcache.db
文件的大小为500KB。然后,我简单地将其压缩(httpcache.db.zip
大小变为24KB),并尝试测量读取压缩文件所需的时间。压缩文件需要90微秒。但是,根据我的测量,解压缩该文件大约需要1000微秒的时间(总共1090微对350微)。
然后我尝试使用lz4压缩器。压缩后的大小变为40KB。但是,使用lz4时,仅需80微秒即可解压缩我的原始httpcache.db。它看起来像是一场胜利:90 + 80微秒,而lz4压缩前为350微秒。为确保一切正常,我进行了最后一次运行以验证数字,令人惊讶的是,加载压缩的40KB文件所花的时间与原始500KB的未压缩文件所花费的时间相同。我检查了所有内容,但没有发现代码问题:以某种方式加载40KB或500KB的文件需要350-400微秒,而加载24KB的文件则需要90微秒。唯一的区别(除了文件大小)是文件名/扩展名。我只是将lz4压缩文件从httpcache.db重命名为httpcache.zip,而令我惊讶的是,仅将文件扩展名突然“放大”了文件I / O 200%:按预期加载40KB httpcache.zip
文件将需要90微秒。
[尝试了不同的事情之后,如果文件的扩展名是.db
或.bin
,似乎读取速度很慢;如果扩展名是.zip
,.txt
或根本没有扩展名,则速度很快。
很明显,Windows根据文件扩展名以某种方式弄乱了文件io(我使用的是最新的Win10专业版,运行在2020 macbook pro 16的bootcamp上)。我为文件所在的文件夹禁用了防病毒功能,但仍然得到了相同的结果。任何想法,这是怎么回事,以及为什么文件扩展名对文件io的影响如此之大?
这是我要测量的代码:
int main()
{
std::string fdataZip, fdata;
{
static const char dbName[] = "../data/httpcache.db.zip"; // 24KB
auto t0 = timeMicro();
readFile(dbName, fdataZip);
auto t1 = timeMicro();
LOG("%s load time: %lld micro", dbName, t1 - t0);
}
{
static const char dbName[] = "../data/httpcache.db"; // 40 KB
auto t0 = timeMicro();
readFile(dbName, fdata);
auto t1 = timeMicro();
LOG("%s load time: %lld micro", dbName, t1 - t0);
}
}
和readFile为:
void readFile(const char* fileName, std::string& fileData)
{
fileData.clear();
if (FILE* fl = fopen(fileName, "rb"))
{
fseek(fl, 0, SEEK_END);
long length = ftell(fl);
fseek(fl, 0, SEEK_SET);
if (length > 0)
{
fileData.resize(length);
(void)fread(&fileData[0], 1, length, fl);
}
fclose(fl);
}
}
[timeMicro
使用QPC时钟实现。
我得到的样本运行的输出:
0:000 ... start
0:002 ../data/httpcache.db.zip load time: 97 micro
0:003 ../data/httpcache.db load time: 450 micro