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
而不是<