Лучшие (scala и другие языки, нацеленные на java vm) оптимизации - PullRequest
6 голосов
/ 27 января 2011

Я только что читал о реализации scala специализации дженериков , и это действительно привлекло мое внимание увеличением скорости, которого они достигли с помощью этой функции.Мне было интересно, какие еще функции есть у языков, нацеленных на реализованный Java-VM, которые на самом деле заставили их работать лучше, чем Java?Я знаю, что чем дальше сгенерированный код удаляется от Java, тем ниже его производительность.Поэтому мне действительно интересно, какие еще функции может быть реализован языком для достижения лучшей производительности в Java.

Пожалуйста, не отвечайте на этот вопрос, говоря о действительно хороших функциях Scala в дополнение к Java, я говорю строго о производительности.

Также, если у вас есть предложения, которые еще не были реализованы, пожалуйста, ответьте!

Спасибо!

Ответы [ 3 ]

13 голосов
/ 27 января 2011

Scala поддерживает оптимизацию хвостового вызова , которую Java, только через JVM, пока не полностью поддерживает .

5 голосов
/ 27 января 2011

Scala оптимизирует такие вещи, как

val nullSafeToString = "" + foo

до

val nullSafeToString = String.valueOf(foo)

Java нет, в Java это выглядит как

val nullSafeToString = new StringBuilder("").append(foo)

, что занимает в 4 раза большебайт-код, чем более простой код Scala и создает новый экземпляр StringBuilder и бесполезный String.

С одной стороны, JVM была создана для поддержки вещей, которые они планировали использовать в Java, даже если JVMвыполняет только байт-код.

Существуют функции, которые отсутствуют целую вечность для лучшей поддержки функциональных (tailcalls) и нетипизированных языков (InvokeDynamic).

Но с другой стороны, я удивлен, насколько безболезненно JIT-компилятор может оптимизировать сильно абстрагированный код и слои косвенного обращения и в конечном итоге получить код, работающий так же быстро, как код Java.

Я думаю, что шаблон «Pimp My Library» не был бы таким популярным, если бы JVM не могла удалить экземпляры этих простых шаблонов implicit + class RichFoo с помощью escape-анализа.

3 голосов
/ 27 января 2011

Возможно, это слишком тривиально / старо / хорошо известно, но компилятор Java оптимизирует строковые литералы и конкатенации с использованием пула String и StringBuilders:

 String a = "a";
 String b = "a";
 String c = a + b + someUserInput;

будет на самом деле ближе к

 String a = "a";
 String b = a;
 String a_b = "aa";
 String c = new StringBuilder(a_b).append(someUserInput).toString();

или, может быть, даже (не уверен)

 String a_b = "aa";
 String a = a_b.substring(0,1);
 String b = a;
 String c = new StringBuilder(a_b).append(someUserInput).toString();

Кроме того, фокус оптимизации для компилятора Java сместился с компиляции на байт-код (javac) на компиляцию с байт-кода на машинный код (Hotspot). Я думаю, что раньше было больше оптимизаций в javac, но они обнаружили, что это немного преждевременно, учитывая, что Hotspot может выполнять здесь гораздо более тщательную работу (и опираться на знания во время выполнения о реальном оборудовании и шаблонах использования).

Другим интересным аспектом этого является то, что оптимизация Hotspot может улучшить производительность еще долго после того, как код был написан и скомпилирован. Например, описанная выше оптимизация StringBuilder использовала (немного менее эффективный) класс StringBuffer до Java 5. Чтобы получить последние улучшения, вам нужно будет перекомпилировать код (что все же лучше, чем оптимизировать вручную для использования StringBuffer раньше, и в этом случае вам действительно нужно обновить код).

...