英文:
Is mapNotNull more efficient than filter and map?
问题
我之前正在编写一些 Kotlin 代码,对列表进行了筛选,然后进行了映射(这是我之前在 Kotlin 中见过的一种模式),但我意识到只使用 mapNotNull
可能更有效率。我好奇这是否正确,如果是的话,使用 filter
和 map
而不是 mapNotNull
的使用案例是什么。
我最初要做的事情类似于这样:
myList.filterIsInstance<MyObjectType>.map { it.name }
我意识到在这种情况下,代码必须通过整个集合进行筛选,然后必须再次通过筛选后的列表进行映射。所以我最终将代码更改为以下样式:
myList.mapNotNull { if (it is MyObjectType) it.name else null }
在这种情况下,您只需要遍历整个集合一次。除非 mapNotNull
在内部只执行了一个不为空的项的筛选?
这是正确的吗?第二种方法更有效吗?
如果是这样的话,我的下一个问题是,在什么情况下运行 filter
而不是 map
比使用 mapNotNull
更有效,而后者包含将不需要的项映射到 null 的语句。它不会总是增加运行的迭代次数吗?
我觉得我可能漏掉了一些明显的东西,所以任何澄清都将不胜感激,如果这是一个愚蠢的问题,我很抱歉。
英文:
I was writing some Kotlin code that filtered and then mapped a list (which is a pattern I have seen previously in Kotlin), but I realised it may be more efficient to just use mapNotNull
. I was curious if this is true and if so what the use cases for using filter
and map
over mapNotNull
are.
The original thing I was doing looked something like this:
myList.filterIsInstance<MyObjectType>.map { it.name }
I realised in this case the code must run through the entire collection for the filter and then must run through the filtered list again to perform the map.
So I ended up changing the code to look like this:
myList.mapNotNull { if (it is MyObjectType) it.name else null }
In this case you only need to run through the entire collection once. Unless mapNotNull is just performing a filter for not null items under the hood?
Is this correct? Is the second method more efficient?
And if that is the case, my next question is when would running a filter
than a map
ever be more efficient than using mapNotNull
which contains a statement to map unwanted items to null. Will it not always increase the amount of iterations that run?
I have a feeling I may be missing something obvious here, so any clarification is appreciated and sorry if it is a stupid question.
答案1
得分: 1
每个可迭代对象上的这些运算符都会生成一个新的列表,因此使用两个运算符而不是一个会花费更多时间,假设你的逻辑基本相同。额外时间的大部分将用于分配和写入新列表,而不是整个列表的额外迭代。
在没有使用性能基准库的情况下小心测试性能。由于未考虑热身、由于重复操作而在运行时发生的JIT优化、在第一个测试用例的时间中包含了类加载等因素,你的结果可能会大相径庭。
英文:
Each of these operators on the Iterable produces a new List, so using two operators instead of one operator is going to take more time, assuming the logic of what you're doing is basically the same. The bulk of the extra time will be in allocating and writing to the new list, not so much the extra iteration through the whole list.
Be careful benchmarking stuff without using a benchmarking library. Your results could be way off because of you not factoring in things like warm-up, JIT optimizations that happen at runtime due to repeated operations, class loading being included in the time of your first test case, etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论