提问人:Voivoid 提问时间:5/7/2023 最后编辑:wohlstadVoivoid 更新时间:5/8/2023 访问量:100
容器使用 memcpy 优化的单元测试
Unit test that the container uses memcpy optimization
问:
假设有一些自定义的类似容器,它在其复制构造函数中使用 memcpy 优化来 memcpy 简单可构造的对象,而不是调用多个复制构造函数。std::vector
如何对优化是否真正应用进行单元测试?
即
struct foo { /* some members */ };
static_assert(std::is_trivially_copyable_v<foo>);
my_vector<foo> v1{ /* some foo objects */ };
my_vector<foo> v2 = v1; // how do I test that single memcpy was called for all foo objects instead of multiple foo copy ctors? or how do I test that none copy ctors were called at all?
答:
0赞
fabian
5/7/2023
#1
可能有一些方法可以将标准库实现替换为保存有关任何复制的数据(例如,请参阅如何替换 C 标准库函数?),但一般来说,最简单的方法是在其中包含复制实现的附加模板参数中传递:memcpy
struct default_copier
{
void memcpy(void* dest, void const* src, size_t size) const noexcept
{
std::memcpy(dest, src, size);
}
};
template<class T, class Copier = default_copier>
class my_vector
{
[[no_unique_address]] Copier m_copier;
T m_values [10]{};
public:
my_vector()
{
}
void fill_first(T const* values, size_t size)
{
if constexpr (std::is_trivially_copyable_v<T>)
{
m_copier.memcpy(m_values, values, sizeof(T) * size);
}
else
{
std::copy_n(values, size, m_values);
}
}
Copier& copier()
{
return m_copier;
}
};
struct test_copier
{
size_t m_memcpyUseCount{ 0 };
void memcpy(void* dest, void const* src, size_t size)
{
std::memcpy(dest, src, size);
++m_memcpyUseCount;
}
};
int main() {
{
my_vector<int, test_copier> vectorOfTriviallyCopyable;
int buffer[2]{};
vectorOfTriviallyCopyable.fill_first(buffer, std::size(buffer));
assert(vectorOfTriviallyCopyable.copier().m_memcpyUseCount == 1);
}
{
my_vector<std::string, test_copier> vectorOfNonTriviallyCopyable;
std::string buffer[2]{};
vectorOfNonTriviallyCopyable.fill_first(buffer, std::size(buffer));
assert(vectorOfNonTriviallyCopyable.copier().m_memcpyUseCount == 0);
}
return 0;
}
评论
0赞
Paul Sanders
5/8/2023
我们什么时候停止信任编译器了?
1赞
Eljay
5/8/2023
@PaulSanders • 我信任编译器。我不相信键盘后面的猴子拿着枪。
1赞
Paul Sanders
5/8/2023
@Eljay 尤其是当我拿着枪😸的时候
0赞
Voivoid
5/8/2023
#2
看起来有一些方法可以检测没有复制结构:
如果一个自定义容器是类似 std 的(这意味着它可以通过分配器进行参数化),则可以使用模拟分配器来观察任何容器的元素复制构造是否是通过观察分配器的方法完成的。如果没有方法调用,您可以非常确定没有进行复制构造。construct
construct
评论