我正在开发一个特征检测程序,它使用了图像中各种地标的统计模型。该模型使用了大约100个不同的地标,每个地标的相关数据由16个双面矩阵组成,每个矩阵的大小约为160x160。
目前,我正在为每个地标使用一个文本文件,并将每个矩阵的值存储为一个空格分隔的行。为了读取数据,我每次从每个文件中读取一行,并将其传递给一个函数,该函数从该行生成一个字符串流,然后每次从该流读取矩阵的值。
在我的电脑上,这需要大约90秒的时间来加载-4000万肯定有一种更快捷的方法,但我在谷歌上没有发现任何有用的东西,而且我对这类事情也没有经验。
如有任何建议,我将不胜感激。
编辑: Loki让我发布代码,所以我在下面展示了它。每个地标都调用一次loadFromFile。每个里程碑文件的第一行说明模型对这个地标使用了多少级别(每个级别使用四个矩阵;默认情况下有四个级别)。这是个可怕的烂摊子,但我不知道为什么这么慢。
void loadFromFile(string filename)
{
ifstream modelData(filename.c_str(), ifstream::in);
string line;
getline(modelData,line);
int numberOfLevels = atoi(line.c_str());
for(size_t ii = 0; ii < numberOfLevels; ++ii)
readProfileStats(modelData);
modelData.close();
}
void readProfileStats(ifstream& fileStream)
{
string line;
getline(fileStream, line);
Vector meanProfile = readMatrixFromString(line);
getline(fileStream, line);
Matrix principalComponents = readMatrixFromString(line);
getline(fileStream, line);
Matrix covarianceMatrixInverse = readMatrixFromString(line);
m_statsLevels.push_back(ProfileStats(meanProfile, principalComponents, covarianceMatrixInverse));
}
Matrix readMatrixFromString(const string& line)
{
stringstream stream(line);
size_t numRows;
size_t numCols;
stream >> numRows;
stream >> numCols;
Matrix matrix(numRows,numCols);
for(int ii = 0; ii < numRows; ++ii)
{
for(int jj = 0; jj < numCols; ++jj)
stream >> matrix(ii,jj);
}
return matrix;
}发布于 2011-12-16 21:47:48
试着使用scanf库:
r1.cpp
> cat r1.cpp
#include <iostream>
int main()
{
double x;
long count = 0;
while(std::cin >> x)
{
++count;
}
std::cout << count << ": " << x << "\n";
}r2.cpp
> cat r2.cpp
#include <iostream>
#include <stdio.h>
int main()
{
double x;
long count = 0;
while(fscanf(stdin, "%lf", &x) == 1)
{
++count;
}
std::cout << count << ": " << x << "\n";
}结果系列
> g++ -O3 r1.cpp -o r1
> time (cat t | ./r1)
40000000: 9.36e+08
real 0m57.669s
user 0m56.992s
sys 0m1.688s
> g++ -O3 r2.cpp -o r2
> time (cat t | ./r2)
40000000: 9.36e+08
real 0m14.419s
user 0m13.897s
sys 0m1.352s因此,使用IOstream读取4000万个数字所花费的时间比我预期的要长大约60秒。而只用了15秒的扫描。所以大约快4倍。
我也做了同样的事情,但只是写二进制值的双子文件。
请注意,您必须将它们写成二进制文件,当然,您还需要丢失所有类型、安全性和可移植性。
double x;
std::cout.write((char*)&x, sizeof(x));r1b.cpp
> cat r1b.cpp
#include <iostream>
int main()
{
double x;
long count = 0;
while(std::cin.read((char*)&x, sizeof(double)))
{
++count;
}
std::cout << count << ": " << x << "\n";
}r2b.cpp
> cat r2b.cpp
#include <iostream>
#include <stdio.h>
int main()
{
double x;
long count = 0;
while(fread(&x, sizeof(double), 1, stdin) == 1)
{
++count;
}
std::cout << count << ": " << x << "\n";
}结果二进制
> time (cat t2 | ./r1b )
40000000: 9.36e+08
real 0m3.930s
user 0m3.592s
sys 0m0.984s
> time (cat t2 | ./r2b )
40000000: 9.36e+08
real 0m2.110s
user 0m1.840s
sys 0m0.804s发布于 2011-12-16 21:29:42
正如注释中所建议的那样,这里的问题是必须将数据从文本转换为数值。这可以通过以二进制格式存储数据来完全消除。有些库可以处理这个问题,比如hdf5。使用这样一个流行的库有很多好处,因为您可以得到一个完整的预先构建的工具链,以及除了C++之外的许多其他语言的支持。但是,缺点是,在学习如何使用这些系统之前,还需要做一些很好的工作。如果这是一个一次性的研究项目,我建议您强烈考虑另一种更简单的方法:一旦您的结构第一次创建,只需将数据结构fwrite或mmap映射到磁盘文件中即可。然后,创建一个函数,将该二进制文件直接映射到您的数据结构中。给程序调用mmap函数而不是解析函数的选项。你会看到这样做会大大加快速度。
https://stackoverflow.com/questions/8539846
复制相似问题