我认为此页面上的所有意见和建议都是合理的,但我决定尝试一个小实验。
令我惊讶的是,最快的方法并不是我们理论上预期的方法。
我尝试了一些代码如下。
#include <cstring>
#include <iostream>
#include <string>
#include <chrono>
using std::string;
using std::chrono::system_clock;
inline void mycopy( double* a, double* b, size_t s ) {
while ( s > 0 ) {
*a++ = *b++;
--s;
}
};
// to make sure that every bits have been changed
bool assertAllTrue( unsigned char* a, size_t s ) {
unsigned char v = 0xFF;
while ( s > 0 ) {
v &= *a++;
--s;
}
return v == 0xFF;
};
int main( int argc, char** argv ) {
alignas( 16 ) char bufA[512], bufB[512];
memset( bufB, 0xFF, 512 ); // to prevent strncpy from stoping prematurely
system_clock::time_point startT;
memset( bufA, 0, sizeof( bufA ) );
startT = system_clock::now();
for ( int i = 0; i < 1024 * 1024; ++i )
strncpy( bufA, bufB, sizeof( bufA ) );
std::cout << "strncpy:" << ( system_clock::now() - startT ).count()
<< ", AllTrue:" << std::boolalpha
<< assertAllTrue( ( unsigned char* )bufA, sizeof( bufA ) )
<< std::endl;
memset( bufA, 0, sizeof( bufA ) );
startT = system_clock::now();
for ( int i = 0; i < 1024 * 1024; ++i )
memcpy( bufA, bufB, sizeof( bufA ) );
std::cout << "memcpy:" << ( system_clock::now() - startT ).count()
<< ", AllTrue:" << std::boolalpha
<< assertAllTrue( ( unsigned char* )bufA, sizeof( bufA ) )
<< std::endl;
memset( bufA, 0, sizeof( bufA ) );
startT = system_clock::now();
for ( int i = 0; i < 1024 * 1024; ++i )
memmove( bufA, bufB, sizeof( bufA ) );
std::cout << "memmove:" << ( system_clock::now() - startT ).count()
<< ", AllTrue:" << std::boolalpha
<< assertAllTrue( ( unsigned char* )bufA, sizeof( bufA ) )
<< std::endl;
memset( bufA, 0, sizeof( bufA ) );
startT = system_clock::now();
for ( int i = 0; i < 1024 * 1024; ++i )
mycopy( ( double* )bufA, ( double* )bufB, sizeof( bufA ) / sizeof( double ) );
std::cout << "mycopy:" << ( system_clock::now() - startT ).count()
<< ", AllTrue:" << std::boolalpha
<< assertAllTrue( ( unsigned char* )bufA, sizeof( bufA ) )
<< std::endl;
return EXIT_SUCCESS;
}
结果(许多类似结果之一):
strncpy:52840919,AllTrue:真
memcpy:57630499,AllTrue:真
memmove:57536472,AllTrue:真
我的副本:57577863,AllTrue:真
看起来像:
- memcpy、memmove 和我自己的方法有类似的结果;
- strncpy 有什么魔力,所以它是最好的,甚至比 memcpy 还要快?
好笑吗?