加载文本文件,优化
C++ Load text file, optimization
这是我的源代码加载文本文件,并将每行分隔为单个项目(单词)。
如何进一步优化代码?测试空行(和其他结构)(在我看来)有点低效....
typedef std::vector < std::string > TLines;
typedef std::vector < std::vector < std::string > > TItems;
TItems TFloadFile ( const char * file_name )
{
//Load projection from file
unsigned int lines = 0;
char buffer[BUFF];
FILE * file;
TItems file_words;
TLines file_lines;
file = fopen ( file_name, "r" );
if ( file != NULL )
{
for ( ; fgets ( buffer, BUFF, file ); )
{
//Remove empty lines
bool empty_line = true;
for ( unsigned i = 0; i < strlen ( buffer ); i++ )
{
if ( !isspace ( ( unsigned char ) buffer[i] ) )
{
empty_line = false;
break;
}
}
if ( !empty_line )
{
file_lines.push_back ( buffer );
lines++;
}
}
file_words.resize ( lines + 1 );
for ( unsigned int i = 0; i < lines; i++ )
{
char * word = strtok ( const_cast<char *> ( file_lines[i].c_str() ), " t,;rn" );
for ( int j = 0; word; j++, word = strtok ( 0, " t;rn" ) )
{
file_words[i].push_back ( word );
}
}
fclose ( file );
}
return file_words;
}
for ( unsigned i = 0; i < strlen ( buffer ); i++ )
行效率非常低,因为您每次都要通过循环计算buffer
的长度。然而,这可能会被编译器优化掉。
你在没有reserve()
任何空间的情况下将物品推到std::vector
s上。对于大型文件,这将涉及大量开销,因为为了调整它们的大小,需要复制向量的内容。我刚刚读了@Notinlist的回答,里面已经谈到了std::vector::resize()
的低效率。
与其通过重复的fgets()
调用将每行读取到一个向量中,不如简单地确定文件中的字节数,动态地分配一个char
数组来保存它们,然后将字节转储到其中?然后,您可以解析单词并将它们存储在file_words
中。这将比您当前使用的方法更有效。
在优化之前,你能解释一下文件有多大,代码当前执行需要多长时间,以及为什么你认为它还没有IO绑定(即由于硬盘速度)。你认为需要多长时间?对文件中数据类型的一些概念也会很好(例如平均行长度,空行的平均比例等)。
也就是说,将remove-empty-line循环与单词标记循环结合起来。然后,您可以完全删除TLines,并避免std::string结构和向量推退。我还没有检查这个代码的工作,但它应该足够接近给你的想法。它还包括一个更有效的空行定位器:
if ( file != NULL )
{
for ( ; fgets ( buffer, BUFF, file ); )
{
bool is_empty = true;
for (char *c = buffer; *c != ' '; c++)
{
if (!isspace(c))
{
is_empty = false;
break;
}
}
if (is_empty)
continue;
file_words.resize ( lines + 1 );
char * word = strtok ( buffer, " t,;rn" );
for ( int j = 0; word; j++, word = strtok ( 0, " t;rn" ) )
{
file_words[i].push_back ( word );
}
lines++;
}
fclose ( file );
}
For one
file_lines.push_back ( buffer );
这是一个非常昂贵的行。如果不必使用vector,则可以使用list。可以在完成任务后将列表转换为向量。
如果你绝对需要使用vector来实现这个目的,那么你应该使用一些指数递增,比如:
if(file_lines.size()<=lines){
file_lines.resize((int)(lines * 1.3 + 1));
}
这样,你将有更少的cpu密集型。resize()操作,以最小的内存消耗开销为代价。
简化并转换为std::list
而不是std::vector
。
typedef std::list< std::list< std::string > > TItems;
TItems TFloadFile ( const char * file_name )
{
using namespace std;
//Load projection from file
ifstream file(file_name);
TItems file_words;
string line;
for(getline(file,line); !file.fail() && !file.eof(); getline(file,line))
{
file_words.push_back(list<string>());
list<string> &words(file_words.back());
char *word = strtok((char*)line.c_str(), " t,;rn" );
for(; word; word=strtok( 0, " t;rn" ))
{
words.push_back( word );
}
if(!words.size())
file_words.pop_back();
}
return file_words;
}
- C++ 尝试优化每一帧将数据打印到二进制文件
- 优化从文件加载QImage
- 删除编译器优化并在发布中启用 pdb 文件
- 在 C++ 优化中合并大型二进制文件
- 使用LTO静态链接的可执行文件(链接时间优化):如何使用以前构建的库进行制作
- 在 c++ 中从 txt 文件中提取条目的代码优化问题
- 将多个文件传递给C/C 编译器允许进行概要优化
- C :如何优化复制.txt文件的其余部分
- -O2 优化不会在读取大文件时出圈
- 优化.txt文件的创建速度
- 标志以将IPDB和IOBJ文件从链接时间代码生成优化(LTCG)移动
- 优化文件读数C
- 如何使用objdump在高度优化的对象文件中交错源代码
- 我可以为visualstudio2010中的一些文件打开优化器吗
- 如何优化c++二进制文件读取
- 如何优化C++逐行读取文件到向量中
- 编译器是否会优化未使用的链接文件
- 可靠地使用C++小字符串优化将短 std::字符串从文件转移到内存中
- 优化文件夹中文件重新分区的良好做法
- 使用zlib优化文件写入