代码之家  ›  专栏  ›  技术社区  ›  Joe

最快的报价转义实现?

  •  5
  • Joe  · 技术社区  · 15 年前

    我正在研究一些规范化大量数据的代码。在处理结束时,许多key=“value”对被写到一个文件中。

    “value”部分可以是任何内容,因此在输出点,值必须有任何嵌入的引号转义为\”。

    现在,我正在使用以下内容:

    outstream << boost::regex_replace(src, rxquotesearch, quoterepl);
    // (where rxquotesearch is  boost::regex("\"")  and quoterepl is "\\\\\"")
    

    然而,gprof显示我在这个方法中花费了大部分的执行时间,因为我必须为每行的每个值调用它。

    我很好奇有没有比这更快的方法。我不能使用std::replace,因为我要用两个字符替换一个字符。

    谢谢你的建议。

    4 回复  |  直到 15 年前
        1
  •  6
  •   John Kugelman Syzygies    15 年前

    如果速度是一个问题,您应该使用手写功能来完成此操作。注意使用 reserve() 尽量减少内存分配。

    string escape_quotes(const string &before)
    {
        string after;
        after.reserve(before.length() + 4);
    
        for (string::size_type i = 0; i < before.length(); ++i) {
            switch (before[i]) {
                case '"':
                case '\\':
                    after += '\\';
                    // Fall through.
    
                default:
                    after += before[i];
            }
        }
    
        return after;
    }
    
        2
  •  2
  •   KPexEA    15 年前

    我根本不接受源字符串并构建新的输出字符串。
    我将遍历源字符串并打印每个字符,如果该字符是引号,则在打印之前只打印一个\。

        3
  •  1
  •   Charlie    15 年前

    我一点也不奇怪瑞吉克斯的速度真的很慢——你用一个大的通用锤子来敲一个小钉子。当然,如果您最终需要做一些更有趣的事情,那么regex可能会很快获得简单性方面的优势。

    对于更简单/更快的方法,您可以尝试将转义字符串一次写入一个单独的缓冲区中的一个字符。然后,添加转义就变得很简单了,而且您不会浪费任何时间重新分配字符串或移动字符。最大的困难将是管理缓冲区的大小,但是您可以使用一个向量来实现这一点,并为每个字符串重用相同的向量以避免重复分配。效率的提高很大程度上取决于向量如何工作的细节,但如果需要,您可以将其归结为原始数组和手动内存管理。

    如果使用vector:

    vector<char> buf;
    for( some_iterator it = all_the_strings.begin();
         it != all_the_strings.end(); ++it )
    {
        buf.clear();
        const string & str = *it;
        for( size_t i = 0; i < str.size(); ++i )
        {
            if( str[i] == '"' || str[i] == '\\' )
                buf.push_back( '\\' );
            buf.push_back( str[i] );
        }
        buf.push_back( '\0' );
    
        // note: this is not guaranteed to be safe, see answer comments
        const char * escaped = &buf[0];
    
        // print escaped string to file here...
    }
    
        4
  •  0
  •   DeusAduro    15 年前

    这里有一个使用string::find和string::insert的实现,不确定它的速度是否更快,您必须弄清楚!这里是:

    std::string src = "hey there i have \" all \" over the f\"in pla\"ce\"";
    size_t n = 0;
    while ( (n=src.find("\"",n)) != std::string::npos )
    {
        src.insert(n,"\\");
        n+=2;
    }   
    std::cout << src << std::endl;
    

    打印:

    嘿,我已经“全部”了 “解放军”