Re[3]: Q_QDOC
От: SaZ  
Дата: 08.09.25 11:36
Оценка: 3 (1)
Здравствуйте, sergii.p, Вы писали:

SP>...

SP>это что за IDE такие? Честно говоря не понимаю как IDE может такой вопрос решить. Там же всё от реализации зависит. Условный метод trimmed может быть объявлен как &&, но по факту выделять память.

Visual Studio + ReSharper, CLion, из тулзов — clang tidy имеет соответствующие диагностики.
И да, конкретно в вашем примере изменения перформанса не будет что с мувом что без, потому что под капотом там используется QSharedData (имплементация COW). А если вас так парят кэшмисы на атомарном счётчике ссылок, то вы должны достаточно хорошо понимать такие тонкости =)
Отредактировано 08.09.2025 11:39 SaZ . Предыдущая версия .
Q_QDOC
От: sergii.p  
Дата: 29.08.25 13:35
Оценка:
кто-то может сказать зачем эти альтернативно одарённые скрыли перегрузки в документации? Чтобы ИИ запутать?

#if !defined(Q_QDOC)
    [[nodiscard]] QByteArray toLower() const &
    { return toLower_helper(*this); }
    [[nodiscard]] QByteArray toLower() &&
    { return toLower_helper(*this); }
    [[nodiscard]] QByteArray toUpper() const &
    { return toUpper_helper(*this); }
    [[nodiscard]] QByteArray toUpper() &&
    { return toUpper_helper(*this); }
    [[nodiscard]] QByteArray trimmed() const &
    { return trimmed_helper(*this); }
    [[nodiscard]] QByteArray trimmed() &&
    { return trimmed_helper(*this); }
    [[nodiscard]] QByteArray simplified() const &
    { return simplified_helper(*this); }
    [[nodiscard]] QByteArray simplified() &&
    { return simplified_helper(*this); }
#else
    [[nodiscard]] QByteArray toLower() const;
    [[nodiscard]] QByteArray toUpper() const;
    [[nodiscard]] QByteArray trimmed() const;
    [[nodiscard]] QByteArray simplified() const;
#endif


Имеем такой код:

for (QByteArray line: data.split('\n'))
{
    line = std::move(line).trimmed();


Нормальный человек посмотрит в документацию — перегрузки для && нет — уберёт std::move как излишний и на ровном месте ухудшит производительность.
Re: Q_QDOC
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.08.25 17:53
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>кто-то может сказать зачем эти альтернативно одарённые скрыли перегрузки в документации? Чтобы ИИ запутать?


Ну вероятнно потому, что документация документирует заявленный интерфейс, а вот в плане деталей реализации они хотят оставить себе свободу.
Re: Q_QDOC
От: SaZ  
Дата: 02.09.25 17:42
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>кто-то может сказать зачем эти альтернативно одарённые скрыли перегрузки в документации? Чтобы ИИ запутать?


SP>...


SP>Нормальный человек посмотрит в документацию — перегрузки для && нет — уберёт std::move как излишний и на ровном месте ухудшит производительность.


Нормальные IDE такое давно умеют подсвечивать (когда надо мув и когда нет). Плюс вполне может быть ситуация что у типа будет конструктор перемещения по умолчанию — такое тоже надо документировать?
Re[2]: Q_QDOC
От: sergii.p  
Дата: 02.09.25 19:55
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Нормальные IDE такое давно умеют подсвечивать (когда надо мув и когда нет).


это что за IDE такие? Честно говоря не понимаю как IDE может такой вопрос решить. Там же всё от реализации зависит. Условный метод trimmed может быть объявлен как &&, но по факту выделять память.
Re[4]: Q_QDOC
От: sergii.p  
Дата: 08.09.25 16:50
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Visual Studio + ReSharper, CLion, из тулзов — clang tidy имеет соответствующие диагностики.


эх, решарпер давно не юзал. Надо попробовать. Правда беглый обзор обвинил, что он предлагает писать return std::move(res) что ломает NRVO. Спишем на козни конкурентов.

SaZ>И да, конкретно в вашем примере изменения перформанса не будет что с мувом что без, потому что под капотом там используется QSharedData (имплементация COW)


А тут COW ни при чём.

line.trimmed()

создаёт новую строку и не изменяет старую.

std::move(line).trimmed()

переиспользует память line и новая строка не создаётся. Ну конечно гипотетическим можно представить, что line может быть к этому времени уже с кем-то пошарена и тогда действительно вызовется detach. Но это уже из мира фантазии.

Да и похоже в Qt идёт общая тенденция по отказу от COW. Так что рассчитывать на эту оптимизацию я бы не стал.
Re[5]: Q_QDOC
От: SaZ  
Дата: 09.09.25 12:21
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>Здравствуйте, SaZ, Вы писали:


SaZ>>Visual Studio + ReSharper, CLion, из тулзов — clang tidy имеет соответствующие диагностики.

SP>эх, решарпер давно не юзал. Надо попробовать. Правда беглый обзор обвинил, что он предлагает писать return std::move(res) что ломает NRVO. Спишем на козни конкурентов.

Ну NRVO вроде как не всегда гарантируется. А есть более полный пример где предлагается такой рефакторинг? Могу в CLion глянуть у себя. Пока не сталкивался с тем чтобы он предлагал делать мув там, где это ломало бы nrvo.

SaZ>>И да, конкретно в вашем примере изменения перформанса не будет что с мувом что без, потому что под капотом там используется QSharedData (имплементация COW)

SP>А тут COW ни при чём.

SP>
SP>line.trimmed()
SP>

SP>создаёт новую строку и не изменяет старую.

SP>
SP>std::move(line).trimmed()
SP>

SP>переиспользует память line и новая строка не создаётся. Ну конечно гипотетическим можно представить, что line может быть к этому времени уже с кем-то пошарена и тогда действительно вызовется detach. Но это уже из мира фантазии.

Я просто первый раз вижу такое использование move, поэтому немного запутался.
Я мельком глянул код, такая перегрузка позволяет переиспользовать внутренний буфер QByteArray, получается на одну аллокацию меньше.
А документировать такое не стали, чтобы не забивать доки такими деталями. Мол ожидайте что у вас всегда новый QByteArray, а то что он может переиспользовать существующий буфер — прикладного программиста уже не должно волновать.

SP>Да и похоже в Qt идёт общая тенденция по отказу от COW. Так что рассчитывать на эту оптимизацию я бы не стал.


Ну потому что COW придумали очень задолго до цпп11, в качестве альтернативы move. Собственно со времён Qt4 контейнеры в кутэ практически не менялись, потому что зачем трогать то, что работает . Но тенденция правильная, потому что у COW есть свои накладные расходы. Раньше COW был удобен, а сейчас имеет смысл использовать возможности языка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.