Справочный центр
Часто задаваемые вопросы
Проверка/изменение пароля
Вход в LINE на iPad или ПК с использованием метода разблокировки смартфона
Появляется сообщение «Это сообщение не может быть отображено», и я не вижу отправленных/полученных сообщений чата
Регистрация адреса электронной почты
Необходимые настройки для входа в LINE для iPad или ПК с методом разблокировки смартфона
Резервное копирование истории чата
Я вижу ошибку при резервном копировании истории чата
Телефонные номера, которые невозможно проверить
Об использовании метода разблокировки смартфона для входа в LINE
Перенос учетной записи LINE с номером телефона
Важное объявление
Категория
Проблемы
Создание/перенос учетной записи LINE
Проверка/изменение регистрационной информации
Покупка/использование предметов
Друзья/Группы
Чаты/Звонки/Уведомления
ЛИНИЯ ВООМ
Получите больше от LINE
Безопасность/защита
ЛИНИЯ Оплата
О бизнес-альянсах
Скрытые друзья с преимуществами времени компиляции
Недавно я думал о том, как сократить время компиляции своего кода на C++ (не так ли). Недавно я также видел, как некоторые люди обсуждали так называемую идиому «скрытый друг» в C++ и ее различные преимущества. Одним из заявленных преимуществ скрытых друзей является то, что они упрощают работу компилятора, ускоряя компиляцию. Я думал, что буду исследовать.
Что такое «скрытый друг»?
Скрытый друг — это свободная функция (обычно перегрузка оператора), определенная в определении класса как друг. Затем эта функция не может быть найдена при обычном поиске по символу, но — это , найденный в последующем поиске, зависящем от аргумента. Это имеет несколько преимуществ, начиная от предотвращения неявных преобразований и заканчивая тем, что незначительные опечатки не могут вызвать серьезные изменения в поведении, а также ускорение компиляции.
Действительно ли это ускоряет компиляцию?
Краткий ответ: Определенно. По крайней мере, на моем надуманном тестовом примере, который я построил специально для проверки этого.
Длинный ответ: я собрал некоторый код Python, который будет генерировать некоторые типы и некоторые операторы равенства между ними. Это позволяет нам сгенерировать произвольно большое количество перегрузок operator==
и посмотреть, влияет ли переключение между свободными функциями на скрытые дружественные функции на время компиляции. Если вам интересно, код, который я использовал, можно скачать здесь.
Например, код, сгенерированный для варианта со свободной функцией, выглядит так:
struct T0 { внутренние данные; }; bool operator==(const T0& lhs, const T0& rhs) { return lhs.data == rhs.data; }
, тогда как код, сгенерированный для варианта скрытого друга, выглядит так:
struct T0 { внутренние данные; друг логический оператор == (const T0& lhs, const T0& rhs) { return lhs.data == rhs.data; } };
Временная компиляция этого кода дает довольно четкие результаты:
С 50 типами, каждый из которых вызывает operator==
50 раз, для компиляции версии со свободной функцией требуется примерно в 23 раза больше времени. Это большая разница! Просто для ясности давайте еще раз взглянем на два больших экземпляра рядом:
Куда уходит все это время?!
Разрешение перегрузки! Я полагаю, что разница в том, что набор перегрузок, которые ему нужно отобрать, намного меньше, и он выполняет меньше работы для каждой из них (поскольку ADL не пытается найти преобразования для аргументов, они должны точно совпадать). Это убеждение подкрепляется тем фактом, что если вы определяете функцию в области блока и в объявлении типа просто помечаете ее как друга, то это занимает столько же времени, как если бы вы вообще не объявляли ее другом — поэтому встроенное объявление важно! Это также согласуется с документами ADL, в которых указано, что ADL игнорируется, если символ найден в области блока (тогда как, когда мы делаем вещь со скрытым другом, мы определяем его в области класса).
Что дальше?
Придуманные тестовые примеры всегда должны быть хорошо выдержаны. Если кто-то захочет попробовать это на большой базе реального кода, мне будет очень интересно, каковы будут результаты! Также стоит отметить, что я не использовал никаких шаблонов, которые всегда доставляют удовольствие во время компиляции.