После прочтения в блогах у меня складывается впечатление, что типы тегов, предоставляемые бесформенными, не требуют дополнительных затрат времени выполнения.
- верно ли, что преобразование экземпляра необработанного типа в тегированный тип не имеет накладных расходов времени выполнения?
- верно ли, что преобразование экземпляра необработанного набора в коллекцию тегового типа не имеет накладных расходов?
С соответствующим исходным кодом теговых типов из бесформенного:
object tag {
def apply[U] = new Tagger[U]
trait Tagged[U]
type @@[+T, U] = T with Tagged[U]
class Tagger[U] {
def apply[T](t : T) : T @@ U = t.asInstanceOf[T @@ U]
}
}
Для Вопроса 1 с примером кода:
trait IdTag
type Id = Long @@ IdTag
val id1: Id = tag[IdTag][Long](1000L) // way #1
val helper = tag[IdTag]
val id2: Id = helper[Long](1000L) // way #2
val id3: Id = 1000L.asInstanceOf[Id] // way #3
В пути # 1и # 2 tag[IdTag]
создает экземпляр tag.Tagger[IdTag]
, который является простым объектом. Будет ли компилятор исключать создание, чтобы не было накладных расходов во время выполнения?Или стоимость создания настолько мала, что люди просто пренебрегают им?
Является ли способ № 3 законным и лучшим способом избежать создания промежуточного объекта?
Для вопроса 2 с примером кода:
val m0: Map[Long, Double] = Map(...) // a very large map
val m1: Map[Id, Double] = m0.map(e => tag[IdTag][Long](e._1) -> e._2) // way #1
val helper = tag[IdTag]
val m2: Map[Id, Double] = m0.map(e => helper[Long](e._1) -> e._2) // way #2
val m3: Map[Id, Double] = m0.asInstanceOf[Map[Id, Double]] // way #3
Верно ли, что с точки зрения производительности путь № 3 является лучшим, способ № 2 хуже, так как необходимо пройти по карте и создатьновая карта, путь № 3 является наихудшим, так как ему нужно не только пройти по карте и создать новую карту, но и создать журнал tag.Tagger
s?