Есть ли выигрыш в производительности от использования алгоритмов c++ std(::ranges)::uninitialized_... и стоит ли не использовать constexpr?

Я реализую тип контейнера, которому принадлежит некоторая память, которую я создаю, используя std::make_unique_for_overwrite(). Учитывая, что эта функция специально возвращает std::unique_ptr в неинициализированную память, я хотел использовать алгоритмы неинициализированной памяти, предусмотренные стандартом. Я заметил, что этих функций нет constexpr, только когда пытался написать тесты с использованием static_assert для моего контейнера, только чтобы понять, что мои constexpr конструкторы не такие constexpr в конце концов из-за моих вызовов std::ranges::uninitialized_copy().

Мой вопрос: в чем именно разница между std::ranges::copy() и его неинициализированным братом std::ranges::uninitialized_copy(), и существует ли достаточно значительная разница в производительности, чтобы отказаться от совместимости constexpr?

Возможно, дубликат stackoverflow.com/questions/66030088/…

康桓瑋 07.07.2024 06:40

@康桓瑋 я не спрашиваю, почему это не так constexpr, я спрашиваю, есть ли достаточно значительная разница между этими двумя алгоритмами, чтобы предпочитать использовать один вместо другого

SHIPWECK 07.07.2024 06:45

Вероятно, не....

Jesper Juhl 07.07.2024 06:47

@SHIPWECK Тогда stackoverflow.com/questions/67992613/…?

康桓瑋 07.07.2024 06:49
make_unique_for_overwrite и make_shared_for_overwrite обычно следует использовать с тривиальным типом. Я не понимаю логики, лежащей в основе не ограничивать их этими типами. Для других типов они просто создают объекты по умолчанию. Для тривиальных типов конструктор присваивания и копирования функционально эквивалентен. uninitialized_copy обычно предназначен для управления памятью C, где выделение и построение объектов временно не связаны. Я бы предпочел определить распределитель костюмов и вместо этого создать вектор.
Red.Wave 07.07.2024 11:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая, что эта функция специально возвращает std::unique_ptr в неинициализированную память.

Это не так. Это unique_ptr для объекта, инициализированного по умолчанию (или массива, или объектов). Это не неинициализация: использование алгоритмов uninitialized_* создаст новый объект поверх существующего объекта, что может привести к утечке памяти, если деструктор пропущен.


«Преимущество производительности» этих алгоритмов заключается в том, что альтернативой обычно является конструкция по умолчанию, а затем использование оператора присваивания. Это действительно преимущество «корректности», поскольку вы не можете ожидать, что универсальные объекты будут конструируемыми по умолчанию, но в качестве побочного эффекта вы избегаете (возможно, дорогостоящего) конструктора по умолчанию.


И когда у вас есть два выбора между «constexpr-дружественным» алгоритмом и более производительным алгоритмом, используйте if consteval и используйте оба.

О, спасибо! Тогда в чем разница между std::make_unique и std::make_unique_for_overwrite? Если я не предоставлю аргументов std::make_unique, создаст ли он по умолчанию объект/массив, на который указывает?

SHIPWECK 09.07.2024 21:24

@SHIPWECK В принципе, для классов это не имеет значения. Разница между make_unique<int[100]>() и make_unique_for_overwrite<int[]>(100) заключается в том, что первый инициализируется 100 нулями, а второй инициализируется по умолчанию (т. е. недействителен для чтения, действителен для записи).

Artyer 13.07.2024 22:44

Другие вопросы по теме

Приводит ли наличие вектора, содержащего структуры с неинициализированными членами, к неопределенному поведению?
Попытка инициализировать объекты класса внутри структуры приводит к ошибкам сегментации
Существует ли альтернативный синтаксис для инициализации константного указателя на константные данные?
Почему Swift разрешает использование переменных перед объявлением в глобальной области, но не внутри функций?
Не удалось вычислить аргумент шаблона класса при использовании назначенных инициализаторов с инициализацией списка
Как инициализировать инициализатор_список?
Инициализация статических конечных полей в системном классе Java в JDK 14 и последующих версиях
Можете ли вы объявить указатель C с собственным адресом?
Инициализируются ли члены класса с инициализатором члена снова в конструкторе, если они есть в списке инициализаторов?
Проблема инициализации переменной для калькулятора расстояний в Java с помощью оператора if и else