If I have a `val foo = List<String>` that I want ...
# getting-started
d
If I have a
val foo = List<String>
that I want to turn into a list of value class instances, is the compiler smart enough to optimise out the conversion
foo.map { FooValueClass(it) }
and skip the
map
step? Or will it just box it...
k
It still has to create a new list by iterating through
foo
, just as it would if you did
foo.map { it }
. It may skip boxing each item (I haven't tried).
p
as far as I'm aware, usage of a value class in a generic type argument will box it
👌 2
so a
List<FooValueClass>
will always contain boxed instances
d
Yeah... that's why I asked whether maybe the compiler would be smart enough to see that there's no need for the mapping at all...
p
ah but there is - a
List<String>
contains the unboxed values -
List<FooValue>
would contain the boxed values. The compiler won't know that the first list would be unused afterwards so wouldn't be able to swap the elements.
d
If the first list wasn't saved in a variable at all it would know... but you have a good point, it would make it pretty hard to implement such a thing.
k
Since
String
and
FooValue
are both reference types (not primitive), why can't the compiler be clever enough to store the
FooValue
items unboxed in the (type-erased) List?
d
It's a bit of a pity thought, because I have a bunch of cases where I need to convert lists to value classes and I really only use those lists -- like when I use Android's shared preferences to save a string set, but I need those elements to be typed w/ no performance tradeoffs...
@Klitos Kyriacou The case I wrote above, I saved the original map in
foo
and then made the transformation... who says I won't use foo as a string list...
But if I would have done
val foo = prefs.getStringPreferences("key", emptySet()).map { FooValue(it) }
would maybe have had more chance to be detected by the compiler...
w
Yes it will be boxed. If you are running on JVM and this occurs on a hot path, the JIT compiler might optimize the boxing away after escape analysis. I understand that it feel unsatisfying to be aware of this boxing, but it's generally not the level at which you need to optimize on JVM.
d
True, but that leaves value classes being that much less useful... since the cases where they are really useful are much less worth optimising there (using a single instance here and there w/ no lists) than in this case where there might be a very large list of them to create every time...
So might as well use data classes everywhere... 🙈
Now that I think about it, I guess there is really a case that they ARE worth it in the end... if used in a data class with many value classes as properties and THAT's stored in a list... then they wouldn't be boxed. Thanks for that piece of information though @Wout Werkman... it might help me feel better about using them in such cases that I talked about before if I know they MIGHT get optimised in the end...
👍 1