Какой самый дешевый тип Scala? - PullRequest
8 голосов
/ 05 февраля 2011

Мне нужно использовать тип (любой тип) в качестве маркера неявного в качестве параметра типа, чтобы отличить его от другого неявного.Это странно, но это может быть другой вопрос.

Поскольку я могу использовать любой тип, я подумал о том, чтобы использовать самый дешевый, с точки зрения занимаемой памяти и времени инициализации .В этом случае это может не сильно повлиять на производительность, но интересен вопрос: какой из них является самым дешевым типом Scala?

В Java ответ, очевидно, java.lang.Object.Но у Scala есть несколько «интересных» типов: типы Any, AnyVal и нижние типы с возможной оптимизацией вокруг них.Тип Nothing не может быть создан, поэтому он исключен из этого сравнения.

Ответы [ 5 ]

13 голосов
/ 05 февраля 2011

Это зависит от вашей конкретной проблемы, но самая дешевая конструкция в Scala - или на любом языке - должна быть такой, которой вообще не существует ... (по крайней мере, не во время выполнения)

Позвольте мне представить Фантомные типы , позволяющие компилятору статически делать правильные вещи, но стерты в пустоту до того, как они достигнут JVM.

Аналогичным образом вы можете легко различить дваобъекты различного типа, не требующие полей маркера.Это хороший кандидат на case object с, и он отлично работает вместе с сопоставлением с шаблоном.

4 голосов
/ 05 февраля 2011

Я не уверен, что понял, что вы имеете в виду под "самым дешевым типом" ... В Java самый дешевый числовой тип с точки зрения памяти может быть байтом, но по производительности POV Java оптимизирован для работы свнутр.Фактически многие (или большинство) языков оптимизированы для работы с int (даже с механизмами БД).Scala - это язык JVM, поэтому я бы сказал, что лучше использовать int.

UPDATE: , если вопрос касается «помеченного / не помеченного» подходящего типа данных, я бы использовал логический примитив.

если вы наберете boolean в Scala-программе, вы получите тип scala.Boolean.Или, если вы введете float, вы получите scala.Float.Однако, когда вы компилируете свой код Scala в байт-коды Java, Scala будет компилировать эти типы в примитивные типы Java, где это возможно, чтобы получить преимущества производительности примитивных типов Java.

Ничто не является Any, что является добрымObject в Java, и любому Object требуется больше памяти, чем любому примитивному типу

И, кстати, использование логического значения в качестве маркера является естественным, это улучшает читабельность вашего кода (и, следовательно, поддержку, понимание другими).Даже если есть что-то еще, более оптимизированное, я бы не стал делать преждевременную оптимизацию и выбрал бы логическое значение.

3 голосов
/ 06 февраля 2011

Если вы выберете Any или AnyVal, то любой примитив, который вы передадите, будет помещен в коробку, так что, вероятно, его нет.

AnyRef действительно хороший выбор.

Если не происходит параметризация типа, то «примитивы» также являются хорошим выбором - например, Boolean или Int.

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

Еще один интересный вариант - java.lang.Integer (с использованием статического метода valueOf), поскольку он гарантирует равенство ссылок для небольших значений (вам нужно проверить документы, чтобы увидеть точный диапазон), что означает, что не требуется никакого выделения .

1 голос
/ 05 февраля 2011

Поскольку Scala работает поверх Java, я предполагаю, что тот же ответ будет работать и в мире Scala.Scala-объект типа Any - это просто некоторый Java-объект.

В Java я думаю, что примитивный тип, такой как int, short или byte, будет дешевле, чем Object, но эти типы могут быть упакованы / упакованы в Scala.(хотя на 100% не уверен в этом.)

Обновление

Если по какой-то причине это должен быть объект, а не примитивный тип, String может быть лучшим, поскольку строки интернированы в ВМ.Поэтому, как правило, в приложении будет только один экземпляр объекта.

0 голосов
/ 02 марта 2011

Scala переносит типы примитивов, когда вы запускаете вызовы методов оболочки, которые не реализует примитивный тип. То есть 1024 * 512 не оборачивается, но в 1024.toInt * 512 1024 оборачивается.

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