开发者

would you propose this method for copying strings?

开发者 https://www.devze.com 2023-01-24 22:45 出处:网络
To achieve higher performance, would you propose using the method below when copying strings specially when there are a lot of characters in the string, lot more than 12?

To achieve higher performance, would you propose using the method below when copying strings specially when there are a lot of characters in the string, lot more than 12?

 unsigned char one[12]={1,2,3,4,5,6,7,8,9,10,11,12};
 unsigned char two[12];
 unsigned int (& three)[3]=reinterpret_cast<unsigned int (&)[3]>(one);
 开发者_StackOverflowunsigned int (& four)[3]=reinterpret_cast<unsigned int (&)[3]>(two);
 for (unsigned int i=0;i<3;i++)
  four[i]=three[i];


No, (almost) never. Use std::strcpy (although not in this case, since your “strings” aren’t zero terminated), or std::copy, or the std::string copy constructor.

These methods are optimized to do the job for you. If your code (or something similar) happens to be faster than naive character by character copying, rest assured that strcpy will use it underneath. In fact, that is what happens (depending on the architecture).

Don’t try to outsmart modern compilers and frameworks, unless you’re a domain expert (and usually not even then).


Perhaps memcpy / std::copy? Wouldn't those be optimized anyway?


I believe most today's compilers already optimizes string copy. Anyway you should benchmark this, and also compare with memcpy, but I don't think the optimization is worth the loss of readability.


I agree with the other replies here. Usually, attempts to optimize block copying more often than not end up being slower than what your target OS provides. For example, memcpy(), memmove() and the like, usually implement some variation of this algorithm: copy words/halfwords/bytes using GP registers until you hit 16 byte alignment, then use SSE to copy 4 words at a time ( that's 16 chars at a time, provided sizeof(char) == 1 ).

Then again, you can also test the performance of your implementation vs memcpy()/strcpy() and see what you get.


I'm not sure why you're using references here at all.

Do this:

memcpy(two, one, sizeof(two));

Note that your usage is more of a "byte array", especially it being unsigned. Furthermore if you do feel the need to "group" the bytes like that, you'd have more luck grouping them 4s or 8s, given they match typical register sizes.


If you have an issue with string copying, there is always the llvm::StringRef way: provide a reference to the underlying string that cannot alter it. The class attributes are limited to a char const* and a size_t.

Of course, the downside is that YOU have to ensure that the underlying buffer stays allocated for the duration of the use of the StringRef


Using str* is possibly the simplest way to build null-terminated strings in C at least. The performance angle is that before a copy is actually possible the destination position in the destination string needs to be calculated (i e the position of the null byte found). Then the length of the source string must be calculated to ensure that you have enough memory in the destination. This adds overhead (more the longer the string) compared to using memcpy where it is up to you to have a large enough buffer and to keep track of how many bytes you have utilized.

(Then you may have additional complexity if your compiler settings specifies 2-byte characters)

So if your string is 3000 bytes long and you append strings "a" and then "b" each will require scanning through 3000 and 3001 bytes before being able to write the two bytes each in "a" and "b" ('a' + null and 'b' + null). Try to optimize that! Appending "b" to "a" before appending to the 3000 byte string would be much faster.

I personally would use memcpy for destination strings larger than 50 bytes or so. The code becomes a bit more complex but once you've done it a few times it's easy.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号