相对于memset,我可以期待std :: fill_n(ptr,n,0)的性能如何?

ein*_*ica 8 c++ memory memset c++-standard-library c++11

对于作为ptr指针的迭代器,std::fill_n(ptr, n, 0)应该做同样的事情memset(ptr, 0, n * sizeof(*ptr))(但请参阅@ KeithThompson对此答案的评论).

对于C++ 11/C++ 14/C++ 17模式下的C++编译器,我可以期望将这些条件编译为相同的代码吗?当/如果它们没有编译成相同的代码,是否与-O0有显着的性能差异?-O3?

注意:当然,一些/大多数答案可能是特定于编译器的.我只对一两个特定的编译器感兴趣,但请写下你知道答案的编译器.

lcs*_*lcs 6

答案取决于您对标准库的实现.

例如,MSVC有几种std::fill_n基于您尝试填充的类型的实现.

std::fill_n使用char*signed char*或调用unsigned char*它将直接调用memset以填充数组.

inline char *_Fill_n(char *_Dest, size_t _Count, char _Val)
{   // copy char _Val _Count times through [_Dest, ...)
_CSTD memset(_Dest, _Val, _Count);
return (_Dest + _Count);
}
Run Code Online (Sandbox Code Playgroud)

如果你用另一种类型打电话,它将填写一个循环:

template<class _OutIt,
class _Diff,
class _Ty> inline
_OutIt _Fill_n(_OutIt _Dest, _Diff _Count, const _Ty& _Val)
{   // copy _Val _Count times through [_Dest, ...)
for (; 0 < _Count; --_Count, (void)++_Dest)
    *_Dest = _Val;
return (_Dest);
}
Run Code Online (Sandbox Code Playgroud)

确定特定编译器和标准库实现的开销的最佳方法是使用两个调用来分析代码.