Разница в производительности между def и val

Рассмотрим приведенный ниже код, в котором я передаю метод и функцию в качестве параметра для map().

  val list1:List[Int]=List(10,20,30)

  def func1(x:Int):Int={
      x+10
  }

  list1.map(func1)
  list1.map(_+10)

У меня есть несколько вопросов о расширении ETA:

  • Есть ли разница в производительности при использовании метода вместо функции, особенно если метод внутренне преобразуется в функцию?
  • Есть ли разница в производительности между def x:Int=10 и val x:Int=10?
  • Я читал, что параметр вызова по имени на самом деле является методом, который не принимает никаких параметров. Теперь, если методы не являются объектами, как мы можем использовать метод в качестве значения параметра?

person codingsplash    schedule 08.02.2017    source источник


Ответы (2)


Между выражениями, о которых вы спрашиваете, нет существенной разницы.

val x берет на себя частное поле.

Обратите внимание, что vs.map(_+10) встраивает функцию по сравнению с vs.map(x => f(x)). Но вы должны создать объект функции в любом случае.

Аргумент вызова по имени => X представляет собой () => X под капотом.

В REPL используйте javap, чтобы показать код. -c для кода, -v для подробностей.

scala> vs.map(f)
res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

scala> :javap -pv -
[snip]
person som-snytt    schedule 08.02.2017
comment
=›X на самом деле () =›X, тогда как мы вызываем функцию без () - person codingsplash; 09.02.2017
comment
Определение вызова по имени заключается в том, что ссылка оценивает выражение; он делает это, вызывая функцию. - person som-snytt; 09.02.2017

Одно из отличий заключается в том, что значения val измеряются при загрузке класса, а def — при вызове.

Простой пример: скажем, у вас есть 100 000 val переменных в классе (ради аргумента), запуск системы может занять много времени. Но если у вас есть def A, в котором декларируется 100К val. Производительность будет снижена только при вызове A.

person Shawn Xiong    schedule 08.02.2017