Насколько эффективен компилятор Scala при повторном использовании известных результатов функций? - PullRequest
7 голосов
/ 01 октября 2010

Я работаю в аналитической системе на основе Scala (http://www.hiringthing.com), и обнаруживаю, что часто задаю себе следующий вопрос. Если мне дадут «чистую» функцию без побочных эффектов, если я нажму эту функцию дважды с теми же входными данными, могу ли я ожидать, что компилятор будет повторно использовать значение, сгенерированное при первом запуске, или он снова пройдет весь код. Другими словами, является ли первый приведенный ниже пример более эффективным, чем второй?

def add(x: Int, y: Int) = x + y * 10000000000

val a = add(1,2)
do_something(a)
do_another_thing(a)

против

def add(x: Int, y: Int) = x + y * 10000000000

do_something( add(1,2) )
do_another_thing( add(1,2) )

Если компилятор действительно может оптимизировать второй случай, есть ли ограничения сложности функции?

Что я хочу сделать, так это избегать многократного выполнения некоторых сложных математических функций просто для удобства программирования ...

Спасибо

Ответы [ 3 ]

9 голосов
/ 01 октября 2010

Из того, что я видел, компилятор Scala вообще не оптимизирует это.JVM может, если сможет определить, что результаты не изменятся, но часто у нее нет хорошего способа узнать.

Так что, как правило, если это тривиальное вычисление, это не имеет значения,и потому, что это тривиально, и потому что JVM может понять, что ему нужно сделать это только один раз.Если это сложно, а скорость важна, вы должны использовать метод val a =, если у вас нет тестов, демонстрирующих, что JVM достаточно умна в этом случае.

Обратите внимание, что иногда неудобно размещать значения,Есть два способа обойти это.Во-первых, обратите внимание, что почти все может быть заменено эквивалентным выражением в фигурных скобках, поэтому исключения могут встречаться реже, чем вы думаете.Также этот метод может быть полезен при определенных обстоятельствах:

def reuse[A,B](a: A)(f: A => B) = f(a)
reuse(add(1,2))( a => { do_something(a); do_another_thing(a)})
5 голосов
/ 01 октября 2010

Без системы эффектов компилятор просто не может решить повторно использовать метод (или Function) возвращаемых значений.

Как и в случае с большинством языков на протяжении всей истории вычислений, вы должны удалить избыточность из своих алгоритмов.

5 голосов
/ 01 октября 2010

Компилятор scala не пытается оптимизировать любые вызовы функций или методов, если только вы не используете аннотацию @inline (и даже это не гарантируется).Тем не менее, JVM и, в частности, JIT-компилятор Hotspot, почти наверняка смогут встроить вызов «add» в ваших примерах, а затем смогут удалить результирующие общие подвыражения.

Как всегда, когда задаете вопросы об оптимизации производительности и компиляции, не следует принимать ответы за Евангелие без тщательного профессионального тестирования.Прошлые показатели не являются гарантией будущих доходов.Содержание может осесть во время доставки.Если опухоль не проходит через четыре часа, обратитесь к врачу.Все модели старше 18.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...