如何高效地从gsl::span复制数据到std::vector?
问题解答
一、复制数据的最优方案
要把gsl::span里的数据高效复制到std::vector,最靠谱的高效做法是:
- 先把目标vector调整到合适大小:
destData.resize(srcData.size()); - 直接用
std::memcpy拷贝——因为gsl::span本身保证数据是连续存储的,完全可以安全这么做:
void WriteBuffer(std::vector<std::byte>& destData, const gsl::span<const std::byte>& srcData) { destData.resize(srcData.size()); std::memcpy(destData.data(), srcData.data(), srcData.size_bytes()); }
这种写法和std::span被优化成单次内存拷贝的效果完全一致。
当然也可以用vector的assign函数,代码更简洁:
destData.assign(srcData.begin(), srcData.end());
但因为gsl::span的迭代器是自定义类型,编译器大概率没法把它优化成内存拷贝,所以还是直接用memcpy效率更有保障。
二、关于gsl::span无法被std::copy优化的原因
你的理解完全正确:std::copy能把std::span的迭代器操作优化成memmove/memcpy,是因为标准库明确知道std::span的迭代器是连续随机访问迭代器,指向的内存是连续的,编译器的优化逻辑能识别这种标准迭代器。而gsl::span的迭代器是自定义类型,编译器的标准库优化逻辑没针对它做适配,没法自动推断出它指向连续内存,所以只能按普通迭代器逐字节复制。
不过不是所有自定义迭代器都会有这个问题:如果自定义迭代器符合C20引入的连续迭代器概念,而且编译器的标准库实现支持对这类迭代器做优化,那std::copy同样能被优化成内存拷贝。但gsl::span的迭代器是在C20之前设计的,没适配这个新标准,所以触发不了优化。
另外,STL自带容器的迭代器(比如std::vector、std::array的迭代器)都是标准的连续随机访问迭代器,编译器能识别并优化,不会出现gsl::span的问题。
内容的提问来源于stack exchange,提问作者StkOverflowSellsUrDataToOpenAI
相关产品推荐
相关产品推荐

