Wstęp:Scala - wydajność Run-czas TypeTags, ClassTags i WeakTypeTags
...
TypeTag[T]
hermetyzuje reprezentacji typu runtime pewnego rodzaju kompilacjiT
. ...
...TypeTag
s są zawsze generowane przez kompilator. ... [1]
TypeTag
y znajdują się w scala.reflect.**
pakietach. Inna SO answer wspomina, że korzystanie z odbicia w Javie wiąże się ze spadkiem wydajności w aplikacji.
Pytanie:
W jakim stopniu TypeTag
s, ClassTag
s i WeakTypeTag
s Use Java odbicie w czasie wykonywania? Są generowane w czasie kompilacji, ale czy powodują one zwiększenie wydajności podczas działania?
Przykład:
def isOfType[A : ClassTag : TypeTag, E : ClassTag : TypeTag](actual: A, expected: E): Boolean = {
actual match {
case _ : E if typeOf[A] =:= typeOf[E] => true
case _ => false
}
}
assert(isOfType(List.empty[Int], List.empty[Int]))
assert(!isOfType(List.empty[String], List.empty[Int]))
Choć znaczniki są generowane w czasie kompilacji, mogę czuć opóźnienie podczas uruchamiania go. Czy porównania typów używają mniej wydajnego odbicia Java pod maską?
Czy można powiedzieć, że narzut typowania jest w tym przypadku nieistotny, czy też sugerowałbyś uniknięcie go tam, gdzie to możliwe? (Mam świadomość, że jest to nieco subiektywne, a jedynie mikro-benchmarking może dać prawidłowy wgląd). Co z wyrażeniem dopasowania 'case _: E'? AfaIk 'porównań ClassTag' są zaangażowane tutaj, czy są one również wykonywane bez odbicia Java? – mucaho
To zależy (szokujące, wiem). Z pewnością nie zawsze jest to pomijalne, ponieważ jest to jeden z wąskich gardeł w naszym własnym projekcie. W zdaniu "case _: E" Java jest zaangażowane, ale nie należy wpadać w pułapkę myślenia, że wszystkie refleksje są powolne, a cały kod bez refleksji jest szybki; w szczególności 'isInstanceOf' jest bardzo szybki, patrz np. http://stackoverflow.com/a/397617/9204 –