Я делаю обзор функций в рамках подготовки к исследовательскому проекту.
Назовите основной язык или языковую функцию, которую сложно оптимизировать, и почему эта функция стоит или не стоит заплаченной цены, или вместо этого просто опровергните мои теории ниже с помощью анекдотических свидетельств. Прежде чем кто-либо пометит это как субъективное, я прошу привести конкретные примеры языков или функций, а также идеи по оптимизации этих функций или важные функции, которые я не рассматривал. Кроме того, любые ссылки на реализации, которые подтверждают правильность моих теорий.
Первое место в моем списке функций, которые сложно оптимизировать, и моих теорий (некоторые из моих теорий не проверены и основаны на мысленных экспериментах):
1) Перегрузка метода времени выполнения (также известная как отправка с использованием нескольких методов или отправка на основе подписи). Сложно ли оптимизировать в сочетании с функциями, позволяющими перекомпиляцию во время выполнения или добавление методов? Или все-таки это сложно? Кэширование сайта вызова - это обычная оптимизация для многих систем времени выполнения, но использование нескольких методов добавляет дополнительную сложность, а также делает его менее практичным для встроенных методов.
2) Преобразование типов / варианты (также известное как типизация на основе значений, а не на основе переменных). Традиционные оптимизации просто не могут быть применены, если вы не знаете, может ли тип чего-либо измениться в базовом блоке. В сочетании с несколькими методами встраивание должно выполняться осторожно, если оно вообще выполняется, и, вероятно, только для заданного порогового значения размера вызываемого объекта. т.е. легко рассмотреть возможность встраивания простых выборок свойств (геттеров / сеттеров), но встраивание сложных методов может привести к раздуванию кода. Другая проблема заключается в том, что я не могу просто назначить вариант регистру и JIT его собственным инструкциям, потому что я должен носить с собой информацию о типе, или каждой переменной требуется 2 регистра вместо 1. На IA-32 это неудобно, даже если улучшено с помощью дополнительных регистров x64. Вероятно, это моя любимая функция динамических языков, поскольку она упрощает очень многие вещи с точки зрения программиста.
3) Первоклассные продолжения - есть несколько способов их реализации, и я сделал это в обоих наиболее распространенных подходах: один - это копирование стека, а другой - реализация среды выполнения для использования стиля передачи продолжения. , стеки кактусов, фреймы стека копирования при записи и сборка мусора. У продолжений первого класса есть проблемы с управлением ресурсами, т. Е. мы должны сохранить все на случай, если продолжение будет возобновлено, и я не знаю, поддерживают ли какие-либо языки оставление продолжения с «намерением» (т. е. «Я не вернусь сюда, поэтому вы можете выбросить эту копию мира» ). Запрограммировав модель потоковой передачи и модель продолжения, я знаю, что обе могут выполнять одно и то же, но элегантность продолжений накладывает значительную сложность на среду выполнения, а также может влиять на эффективность кеширования (локальность стека изменяется больше при использовании продолжений и совместных подпрограмм. ). Другая проблема в том, что они просто не соответствуют оборудованию. Оптимизация продолжений - это оптимизация для менее распространенного случая, и, как мы знаем, общий случай должен быть быстрым, а менее распространенный - правильным.
4) Арифметика указателей и способность маскировать указатели (сохранение в целых числах и т. Д.) Пришлось добавить это, но на самом деле я мог бы жить без этого довольно легко.
Мне кажется, что многие высокоуровневые функции, особенно динамических языков, просто не отображаются на оборудование. В реализациях микропроцессоров есть миллиарды долларов исследований, связанных с оптимизацией чипа, однако выбор языковых функций может обойтись без многих из этих функций (таких как кэширование, сглаживание вершин стека для регистрации, параллелизм команд, буферы адресов возврата, цикл буферы и предсказание переходов). Макроприложения микропрограмм не обязательно работают, как думают некоторые разработчики, и реализация многих языков в виртуальной машине приводит к отображению собственных операций в вызовы функций (т. Е. Чем более динамичен язык, тем больше мы должны искать / кэш во время выполнения, ничего нельзя предположить, поэтому наша смесь инструкций состоит из более высокого процента нелокальных ветвлений, чем традиционный статически скомпилированный код), и единственное, что мы действительно можем хорошо JIT, - это оценка выражений нединамических типов и операции над постоянными или немедленными типами. Мне кажется, что виртуальные машины с байт-кодом и ядра JIT, возможно, не всегда оправданы для определенных языков из-за этого.
Я приветствую ваши ответы.