я прочитал немного связанные с вопросы, но ничего о скорости сравнения memcpy
а также strncpy
,
Что вы рекомендуете отслеживать содержимое строки в критическом разделе?
Я думал о с функции:
memcpy
требуется рассчитать минимальную длину (см. фрагмент 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;
}
}
strncpy
поиск завершает нулевой байт, а ненужный заполняет все последние байты (см. отрывок)
void copy (const std::string src, char (*dst)[20])
{
strncpy (dst, src.c_str(), sizeof(dst)-1);
dst[sizeof(dst)-1] = 0;
}
std::string::copy
как предложено DYPкомментарий …
любая другая идея?
Тесты могут быть выполнены, но они должны основываться на нескольких компиляторах / версиях, разных наборах флагов и различном оборудовании / ОС. Я бы предпочел ответы на основе ваших отзывов / опыта / опыта или математических знаний …
Поскольку это общий вопрос, люди, которые ищут одни и те же вопросы, оценят общий ответ, а не мой конкретный текущий случай.
Для вашей информации, один поток требует записи в файл несколько std::string
что их содержание может быть изменено другим потоком. Я не могу изменить этот другой поток, и этот другой поток очень занят. Если я не блокирую (mutex / spinlock) копию строки, у меня иногда возникают некоторые проблемы. Поэтому я хочу быстро скопировать эти std::string
и напишите их после раздела блокировки.
Прежде всего, я не могу сказать, какая версия быстрее. Как вы, вероятно, знаете, это сильно зависит от вашего компилятора, системы, реализации и т. Д.
Если вы знаете размер заранее (у вас есть std::string
а также size()
принимает O(1)
), это наверное быстрее использовать memcpy
так как у него меньше дел (только копии, без сравнений). Вы можете написать это так:
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';
}
Но я бы никому об этом не поверил. Правильнее всего протестировать все варианты, которые у вас есть, и выбрать конкретный сценарий (о котором я ничего не знаю).
Мой конкретный случай, чтобы быстро хранить некоторые
std::string
в критической секции (спин-блокировка) и после этого сбрасывать эти строки. Поэтому я хочу предотвратить динамическое выделение памяти.
Чего я не понял, так это почему не пользуюсь std::string
, Если вы хотите предотвратить распределение, вы можете reserve()
немного памяти для вашей строки (столько же, сколько будет у вас в массиве char). Или вы можете взять константную ссылку на строку и использовать ее в критическом разделе. Распределение не будет.
Когда вы используете c_str () вместо data (), вы рискуете, что std :: string создаст временную копию для присоединения завершающего 0. И когда вы используете data (), вы не можете использовать stncpy.
Не знаю, есть ли много реализаций, которые действительно делают эту временную копию. Потеря байта для терминатора не такая уж большая проблема. Но: