【问题标题】:Is std::string::replace() optimized for same length strings?std::string::replace() 是否针对相同长度的字符串进行了优化?
【发布时间】:2013-01-14 15:16:56
【问题描述】:

假设,大多数时候我有以下替换方案:

std::string line; // "line" contains a big string.
std::string from = "abcd";
std::string to = "xy";  // to.length() < from.length()
// replace "from" with "to" everywhere in "line"

这里string 类必须放置"xy",然后删除2 个字符,这有效地将line 中的所有字符向左移动。在我的代码的整个生命周期中发生了很多这样的替换。

现在进入真正的问题。我也可以接受以下内容:

// ...
if(to.legnth() < from.length())
  to.resize(from.length(), ' ');
// now to.length() = from.length()
// replace "from" with "to" everywhere in "line"

仅当replace() 针对相同长度的字符串进行了优化时,上述练习才有帮助。应该是因为那是微不足道的;但只是想确认某人是否具有第一手知识。
我尝试通过 Eclipse IDE 浏览到字符串类,但无法深入研究。

【问题讨论】:

  • 如果它不依赖于实现,我会感到非常惊讶(不会是第一次)。
  • @LightnessRacesinOrbit,您在将其标记为关闭之前没有阅读标题吗?
  • 对我来说似乎是一个合理的问题。当目标(要替换)和替换字符串长度相同时,函数std::string::replace()是否优化?
  • 21.4.6.6,p11 的快速浏览似乎没有提到任何关于相同长度的限制或优化,所以我将进行第一次评估;依赖于实现。
  • 另外,我有点希望在to 不大于from 的情况下,replace 的行为类似于remove_if,因为它在单个线性传递中写入, 写入位置始终位于读取位置或读取位置之后。如果是这样,那么与“较小”的情况相比,“等大小”的情况几乎没有什么可优化的。

标签: c++ optimization replace stdstring


【解决方案1】:

我只是看看 MSVC 2008 的实现。他们优化(我省略了一些东西):

_Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
    size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
{
    ...
        if (_Count <= _N0)
        {   // hole doesn't get larger, just copy in substring
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _Count);  // fill hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        }
    else if (_Roff <= _Off)
        {   // hole gets larger, substring begins before hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _Count);  // fill hole
        }
    else if (_Off + _N0 <= _Roff)
        {   // hole gets larger, substring begins after hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + (_Roff + _Count - _N0), _Count); // fill hole
        }
    else
        {   // hole gets larger, substring begins in hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
            _Myptr() + _Roff, _N0); // fill old hole
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
            _Myptr() + _Off + _N0, _Nm);    // move tail down
        _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _N0, _Myres - _Off - _N0, _Myptr() + _Roff + _Count,
            _Count - _N0);  // fill rest of new hole
        }
        ...
    }

请注意,新长度较小的情况和长度相等的情况是相似的。

编辑:可以得出结论,在复制数据后相同长度的字符串的情况下,总共“0”个字符/孔必须移动/填充(即不移动)。因此,实际上不需要优化,但已经很小心了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    相关资源
    最近更新 更多