Taglib:性能和崩溃问题

Taglib: Performance and crashes problems

本文关键字:崩溃 问题 性能 Taglib      更新时间:2023-10-16

我在我的Qt应用程序中使用taglib库(1.7.2)从音乐文件夹中读取mp3文件的一些元数据。问题是我发现它很慢。

例如,这是代码:

QString path = "C:/Music/";
QDir d(path);
QStringList fileTypes;
fileTypes << "*.mp3" ;
d.setNameFilters(fileTypes);
QStringList pathList = d.entryList( QDir::NoDotAndDotDot | QDir::Files);
QTime t;
t.start();
foreach (QString fileName, pathList) {
    fileName = path + fileName;
    TagLib::FileRef *f = new TagLib::FileRef(fileName.toStdWString().c_str());
}
qDebug()<<t.elapsed();

这段代码大约需要 11 秒才能加载包含 400 首歌曲的文件夹,即每个文件大约 28 毫秒。这是非常慢的行:

TagLib::FileRef *f = new TagLib::FileRef(pathFile.toStdWString().c_str());

这么长正常吗?我尝试过使用多线程,但它不会改变任何东西,而且它不是来自我的 PC,因为它足够强大。奇怪的是,一旦加载了所有文件,下次它再次加载文件夹时,它就会立即完成(直到我重新启动操作系统)。


我还有另一个问题。

有时,如果未设置标记,应用会崩溃,并输出:

HEAP[myapp.exe]: 
Invalid address specified to RtlFreeHeap( 0ED90000, 0ED92CC0 )

例如,在以下行:

if (!f->tag()->genre().isNull())

我正在使用Windows 7。

谢谢。

有时,如果未设置标记,应用程序会崩溃,并输出...

这是TagLib中许多奇怪的设计决策之一。当没有标记时,音频属性对象为 NULL。您必须忍受它并添加一些额外的代码来检查 NULL。

奇怪的是,一旦加载了所有文件,下次它再次加载文件夹时,它就会立即完成(直到我重新启动操作系统)

这并不奇怪,因为Windows 7具有非常先进且非常激进的磁盘I/O缓存机制。一旦你"触摸"文件,它就会进入RAM,下次你访问它时 - 它几乎是瞬间的。400 mp3文件并不多,它都适合RAM。

11s 加载包含 400 首歌曲的文件夹

您必须执行400次磁盘寻道,这在典型的硬盘驱动器上通常需要9-11ms(是的,SSD只有0.1ms)。因此,如果文件夹碎片化,您至少有 10*400 = 4 秒的时间来"倒带"驱动器的头部。由于 id3 标签可能出现在文件的开头和结尾,这实际上增加了两次读取次数(您必须倒回到文件末尾),从而提供 2x 时间(约 8 秒)。

简历:读取文件夹的时间接近现实。TagLib 中有许多怪癖(如 NULL 或无法重载文件操作以允许,例如从存档中读取),但它们是可以避免的。TagLib的功能非常好,在许多方面它是独一无二的(宽格式支持)。