最快的报价 - 逃避实施?

时间:2009-07-22 01:34:43

标签: c++ string replace escaping

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

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

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

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

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

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

感谢您的任何建议。

4 个答案:

答案 0 :(得分:6)

如果速度是一个问题,你应该使用手写功能来做到这一点。请注意使用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;
}

答案 1 :(得分:2)

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

答案 2 :(得分:1)

我并不感到惊讶的是,这里的正则表达式真的很慢 - 你正在使用一把大型的通用锤子敲打一个小小的钉子。当然,如果你最终需要做一些更有趣的事情,那么正则表达式很可能会在简单性方面迅速获得优势。

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

如果您使用了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...
}

答案 3 :(得分:0)

这里有一个使用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;

打印出来:

  嘿,我有“全部”   f \“in pla \”ce \“