Пример снижения производительности из-за использования строгих конструкторов данных
Я читаю о строгих конструкторах данных. В связанной вики статье говорится, что
"Аннотации строгости могут ухудшить производительность [потому что] аннотация строгости вынуждает компилятор обеспечить полную оценку поля перед построением конструктора, и если окажется, что поле уже было оценено, то это просто напрасная работа".
Я не понимаю, почему, если поле уже было оценено, оно потрачено впустую, поскольку его значение в любом случае необходимо для применения конструктора.
Есть ли пример, который иллюстрирует эту проблему или другие потери эффективности из-за строгости?
1 ответ
Форсирование значения, даже если оно уже оценено, имеет небольшую, но существующую стоимость.
Если у вас есть указатель на что-то, что может или не может быть уже оценено (thunk или значение), и вы оборачиваете это в ленивый конструктор данных, вы просто копируете этот адрес на его место в памяти. Это быстро.
Если у вас есть такой указатель, и вы хотите сохранить его в строгом конструкторе, вы должны сначала оценить его. Это требует проверки младших битов указателя на возможные теги (трюк, чтобы показать оценку). Если тега нет, вы фактически переходите к этому указателю, чтобы войти в раздел. Прежде чем вы это сделаете, вы должны поместить кадр возврата в стек, чтобы поток выполнения вернулся к вам в конце. Затем thunk оценивает себя, помещает результат в регистр и переходит на обратный адрес. Затем вы можете поместить этот результат в память.
Поэтому, даже если вещь, на которую вы указываете, уже оценена, вам все равно придется выполнить проверку тегов. И я считаю, что в некоторых случаях оцениваемые вещи не имеют тега (это необязательно), поэтому все остальные работы могут все-таки произойти - даром.