C++ C++;加载文本文件,优化
我的源代码加载文本文件,并将每行分隔为单个项目(单词) 如何进一步优化代码?在我看来,测试空行(和其他构造)有点低效C++ C++;加载文本文件,优化,c++,file,optimization,load,delimited-text,C++,File,Optimization,Load,Delimited Text,我的源代码加载文本文件,并将每行分隔为单个项目(单词) 如何进一步优化代码?在我看来,测试空行(和其他构造)有点低效 typedef std::vector < std::string > TLines; typedef std::vector < std::vector < std::string > > TItems; TItems TFloadFile ( const char * file_name ) { //Load projectio
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,;\r\n" );
for ( int j = 0; word; j++, word = strtok ( 0, " \t;\r\n" ) )
{
file_words[i].push_back ( word );
}
}
fclose ( file );
}
return file_words;
}
typedef std::vectorTLines;
typedef std::vector>滴度;
TItems TFloadFile(常量字符*文件名)
{
//从文件加载投影
无符号整数行=0;
字符缓冲区[BUFF];
文件*文件;
TItems文件_字;
TLines文件行;
file=fopen(文件名,“r”);
如果(文件!=NULL)
{
用于(;fgets(缓冲区、缓冲区、文件);)
{
//删除空行
bool empty_line=true;
for(无符号i=0;i
谢谢你的帮助…一个
file_lines.push_back ( buffer );
那是一条非常昂贵的线。如果您不必使用vector,那么可以使用列表。完成任务后,可能会将列表转换为向量
如果您确实需要为此使用向量,那么您应该使用一些指数增量,例如:
if(file_lines.size()<=lines){
file_lines.resize((int)(lines * 1.3 + 1));
}
if(file_lines.size()为一个
file_lines.push_back ( buffer );
这是一个非常昂贵的行。如果你不必使用vector,那么就使用列表。也许在你完成工作后,可以将列表转换为vector
如果您确实需要为此使用向量,那么您应该使用一些指数增量,例如:
if(file_lines.size()<=lines){
file_lines.resize((int)(lines * 1.3 + 1));
}
if(file_lines.size()for(unsigned i=0;i
的行效率很低,因为每次通过循环都要计算buffer
的长度。但是,编译器可能会对此进行优化
您正在将项目推送到std::vector
s上,而没有reserve()
ing任何空间。对于大文件,这将涉及大量开销,因为需要复制向量的内容才能调整其大小。我刚刚读到@Notinlist的答案,其中已经谈到了std::vector::resize()的低效性
而不是通过重复的fgets()将每一行读入向量
调用,您能不能不简单地确定文件中的字节数,动态分配一个字符
数组来保存它们,然后将字节转储到其中?然后,您可以解析单词并将它们存储在文件\u单词
中。这将比您当前使用的方法更有效。的行(无符号i=0;i
效率很低,因为每次通过循环都要计算buffer
的长度。但是,编译器可能会对此进行优化
您正在将项目推送到std::vector
s上,而没有reserve()
ing任何空间。对于大文件,这将涉及大量开销,因为需要复制向量的内容才能调整其大小。我刚刚读到@Notinlist的答案,其中已经谈到了std::vector::resize()的低效性
而不是通过重复的fgets()将每一行读入向量
调用,您能不能不简单地确定文件中的字节数,动态分配一个字符
数组来保存它们,然后将字节转储到其中?然后,您可以解析单词并将它们存储在文件\u单词
中。这将比您当前使用的方法更有效。在优化之前,您能吗解释文件有多大,当前执行代码需要多长时间,以及为什么您认为它尚未绑定IO(即由于硬盘速度)。您认为需要多长时间?了解文件中的数据类型也很好(例如平均行长度、平均空行比例等)
也就是说,将remove空行循环与word tokenising循环结合起来。这样,您就可以完全删除tline,避免std::string构造和向量推回。我还没有检查过这段代码是否有效,但它应该足够接近您的想法。它还包括一个更高效的空行检测器:
if ( file != NULL )
{
for ( ; fgets ( buffer, BUFF, file ); )
{
bool is_empty = true;
for (char *c = buffer; *c != '\0'; c++)
{
if (!isspace(c))
{
is_empty = false;
break;
}
}
if (is_empty)
continue;
file_words.resize ( lines + 1 );
char * word = strtok ( buffer, " \t,;\r\n" );
for ( int j = 0; word; j++, word = strtok ( 0, " \t;\r\n" ) )
{
file_words[i].push_back ( word );
}
lines++;
}
fclose ( file );
}
在优化之前,您能否解释文件有多大,代码当前执行所需的时间,以及为什么您认为它尚未绑定IO(即由于硬盘速度)。您认为需要多长时间?对文件中的数据类型也有一些了解(例如平均行长、平均空行比例等)
也就是说,将remove空行循环与word tokenising循环结合起来。这样,您就可以完全删除tline,避免std::string构造和向量推回。我还没有检查过这段代码是否有效,但它应该足够接近您的想法。它还包括一个更高效的空行检测器:
if ( file != NULL )
{
for ( ; fgets ( buffer, BUFF, file ); )
{
bool is_empty = true;
for (char *c = buffer; *c != '\0'; c++)
{
if (!isspace(c))
{
is_empty = false;
break;
}
}
if (is_empty)
continue;
file_words.resize ( lines + 1 );
char * word = strtok ( buffer, " \t,;\r\n" );
for ( int j = 0; word; j++, word = strtok ( 0, " \t;\r\n" ) )
{
file_words[i].push_back ( word );
}
lines++;
}
fclose ( file );
}
简化并转换为使用std::list
而不是<