I have read some related questions, but nothing about speed comparison between memcpyand strncpy.

What do you recommend to keep track of a string content within a critical section?

  • avoid dynamic memory allocation
  • elegance of code and readable/understandable (few code lines)
  • fast processing (few instructions, prevent branch-miss)
  • able to be optimized by compiler (or having implementations already using optimized instructions)

I was thinking about functions:

  1. memcpy requires to calculate the min length (see snippet on coliru.stacked-crooked.com)

    void copy (char dst[20], const std::string& src)
    {
        if (src.size() < sizeof(dst)) {
            memcpy (dst, src.c_str(), src.size()+1);
        } else {
            memcpy (dst, src.data(), sizeof(dst)-1);
            dst[sizeof(dst)-1] = 0;
        }
    }
    
  2. strncpy searches terminating null byte and unnecessary fills all final bytes (see snippet)

    void copy (const std::string src, char (*dst)[20])
    {
        strncpy (dst, src.c_str(), sizeof(dst)-1);
        dst[sizeof(dst)-1] = 0;
    }
    
  3. snprintf?

  4. std::string::copy as suggested by dyp's comment...

  5. std::copy as again suggested by same dyp's comment...

  6. any other idea?

Benchmarks could be performed but it should be based on several compilers/versions, different flag sets and different hardware/OS. I would prefer answers based on your feedback/background/expertise or on mathematical knowledge...

As this is a general question, people searching for the same related questions will appreciate a general answer, not my own specific current case.

For your information, one thread requires to write within a file some std::string that their content can be changed by another thread. I cannot change this other thread, and this other thread is very busy. If I do not lock (mutex/spinlock) the string copy, I have sometimes some issues. Therefore I want to quickly copy these std::string and write them after the lock section.

有帮助吗?

解决方案

First of all, I cannot tell which version is faster. It highly depends on your compiler, system, implementation, etc, as you probably knows.

If you know the size in advance (you have an std::string and size() takes O(1)), it is probably faster to use memcpy as it has less things to do (just copies, no comparisons). You can write it this way:

void copy(char* buffer, std::size_t buffersize, const std::string& str)
{
    std::size_t len = std::min(buffersize-1, str.size());
    memcpy(buffer, &str[0], len); // using &str[0] instead of data()
    buffer[len] = '\0';
}

But I wouldn't take the word of anyone on that. The right thing to do is test all variations you have and decide for your specific scenario (that I know nothing about).


My specific case is to store quickly some std::string within a critical section (spin lock) and to dump these strings after. Therefore I want to prevent dynamic memory allocation.

What I didn't understand is why don't use std::string. If you want prevent allocations, you can reserve() some memory to your string (the same amount you would have on the char array). Or you can take a const reference to the string and use it on the critical section. No allocation will take place.

其他提示

When you use c_str() instead of data(), you risk that std::string creates a temporary copy in order to attach the terminating 0. And when you use data(), you can't use stncpy.

Don't know if there are many implementations that actually do that temporary copy. Wasting a byte for the terminator doesn't seem to be such a big deal. But:

  • In pure C++ code, you never need c_str(), so why optimize for it?
  • It's not only one byte wasted, it's also time needed for maintaining it
  • Some implementations avoid allocating extra dynamic memory for very short strings. There, beeing able to store one byte more or less matters.
  • Maybe an implementation does Copy-On-Write optimizations for substring operations?
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top