【问题标题】:Always prefer std::string(ptr, size) to std::string(first, last) if possible?如果可能,总是更喜欢 std::string(ptr, size) 到 std::string(first, last) ?
【发布时间】:2020-04-17 05:59:42
【问题描述】:

考虑:

#include <string>
#include <string_view>

using namespace std;

string sv2s_1(string_view sv)
{
    return string(sv.data(), sv.size());
}

string sv2s_2(string_view sv)
{
    return string(sv.begin(), sv.end());
}

sv2s_1中,string最多需要分配一次内部缓冲区。

sv2s_2中,string不知道内部缓冲区应该有多大,所以必须将字符一个一个推回,并可能多次重新分配和复制内部缓冲区。

假设firstlast随机访问迭代器string(first, last)可以使用last - first快速获取其内部缓冲区的大小,所以性能等于string(ptr, size)

问题:如果first last随机访问迭代器,

C++ 标准是否保证 string(first, last) 等效于 string(ptr, size) 在性能方面?

【问题讨论】:

  • 我的意思是有std::distance 所以你不需要随机访问迭代器。另一方面,如果你有一个指针和一个大小,为什么不应该有一个随机访问迭代器呢?

标签: c++ string performance time-complexity standards


【解决方案1】:

我在标准中没有看到这样的要求。标准saysX(i, j) 构造一个序列容器,该容器等于[i, j) 范围,并且表达式的复杂性取决于序列。

查看特定实现,libstdc++precomputes 正向、双向和随机访问迭代器的范围大小:

template<typename InIterator>
void basic_string<CharT, Traits, Alloc>::
_M_construct(InIterator beg, InIterator end, std::forward_iterator_tag) {
    // ...
    size_type dnew = static_cast<size_type>(std::distance(beg, end));
    // ...
}

注意 std::bidirectional_iterator_tagstd::random_access_iterator_tag are derived 来自 std::forward_iterator_tag,并且可以隐式转换成它,所以这个 _M_construct 重载被调用用于前向、双向和随机访问迭代器(以及 C 中的连续迭代器++20)。

【讨论】:

    【解决方案2】:

    std::basic_string's doc 保证以下两个构造函数的复杂性为线性:

    constexpr basic_string( const CharT* s,
                            size_type count,
                            const Allocator& alloc = Allocator() ); // (4)
    
    template< class InputIt >
    constexpr basic_string( InputIt first, InputIt last,
                            const Allocator& alloc = Allocator() ); // (6)
    

    但性能不是保证,也不应该使用另一个来实现。

    注意:构造函数 (6) 采用迭代器采用 InputIterator,而不是 RandomIterator(即使实现可能在迭代器类别上分派)。

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2018-05-13
      • 2022-01-20
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多