https://kotlinlang.org logo
Title
h

haxpor

07/14/2017, 1:54 AM
Android studio often suggests me that I can use stdlib operation i.e.
filter{}
,
map{}
over normal loop code. Yes, I like to use those. But peek into the code from IDE reveals that actually
filter{}
is not better than normal loop as it dynamically creates a new
ArrayList
object to hold filtered elements. So normal loop would slightly has better performance. My question is as IDE suggests me like this - Is the performance that significant (although I can’t feel any difference)? - Is there anyone already did performance test comparing between
filter{}
,
map{}
etc against normal way? - Should I always use lambda functions as also suggested by IDE? (I want to but from above, I didn’t feel safe)
m

marstran

07/14/2017, 7:12 AM
haxpor: With your loop, do you filter it in place or something? Is it mutable?
h

haxpor

07/14/2017, 7:23 AM
I captured the screen for the code before I changed them all to normal loop. It looks like this https://pbs.twimg.com/media/DEqGVA3VwAA-I7a.jpg:large
I don’t think it’s in-place, it return new array for
forEach
as I peeked in. Any idea, or suggestion?
m

marstran

07/14/2017, 7:28 AM
Ok, I think would do something like this:
flyingSaucers.filter { !it.shouldBeRemoved }
             .flatMap { it.bullets }
             .filter { !it.shouldBeRemoved && player.contains(it.x, it.y) }
             .forEach {
                 it.shouldBeRemoved = true
                 player.hit()
                 Game.res.getSound("explode")?.play()
             }
Yes, it does. With your loop, did you just check everything with if-tests? You didn't create a new filtered list there?
Anyway, this should really be a performance problem. You shouldn't really care about this unless it actually becomes a problem. Premature optimization is the root of all evil as they say 😉
I would move that
Game.res.getSound("explode")
outside the loop though.
h

haxpor

07/14/2017, 7:32 AM
Thanks, I understand it might be premature. But are you sure it’s in-place?
m

marstran

07/14/2017, 7:32 AM
No, it is not in place. I was wondering what you did with your loops.
h

haxpor

07/14/2017, 7:32 AM
Ohh, I see. Yup.
I need to filter and do a certain task with it; only for those that is not marked to be removed soon yet.
Thanks, I love to use those stuff, but this thing bugs me from time to time.
Thanks for editing the code, I will keep an eyes on
flatMap
when possible.
m

marstran

07/14/2017, 7:37 AM
You could convert it to a sequence with
.asSequence()
to make it lazy though, but I'm not really sure if it would make a difference here.
h

haxpor

07/14/2017, 7:39 AM
still
filter
will require to create ArrayList to hold result, but
asSequence()
is better too I think.
seem I cannot avoid object creation there before doing anything useful inside the loop
m

marstran

07/14/2017, 7:53 AM
It could be that the JIT will optimize it away even. It shouldn't be a problem.
h

haxpor

07/15/2017, 8:34 AM
I totally didn’t think about
takeIf
or
takeUnless
, so I can combine
forEach
with
takeIf
without creating new object in
filter
before going into the loop.