Thomas Martin
01/05/2024, 8:27 AMtake()
.
We introduce tak()
to compare, which uses subList:
fun <T> List<T>.tak(n: Int): List<T> = this.subList(0, min(this.size, n))
And here are the results :
import io.biznet.commons.utils.tak
println("take");println("\n");println(java.util.Date().toInstant());println("\n");(1..1000000000).forEach { listOf("1","2","3","4").take(3) };println(java.util.Date().toInstant());println("\n");
println("tak");println("\n");println(java.util.Date().toInstant());println("\n");(1..1000000000).forEach { listOf("1","2","3","4").tak(3) };println(java.util.Date().toInstant());println("\n");
take
2024-01-04T22:38:17.654Z
2024-01-04T22:38:37.548Z
tak
2024-01-04T22:38:37.548Z
2024-01-04T22:38:38.515Z
Do we know why it is implemented this way ?
Is it because it handles every Iterable and so can no rely on indexes ?Thomas Martin
01/05/2024, 8:47 AMCLOVIS
01/05/2024, 9:36 AMCLOVIS
01/05/2024, 9:38 AMCLOVIS
01/05/2024, 9:43 AMDo we know why it is implemented this way ?As cited in the documentation above:
Structural changes in the base list make the behavior of the view undefined.Also, not directly written here but it has been a concern elsewhere in the standard library: a view refers to the original list, so it cannot be GC'd. For example, if you have a list of billions of elements, and you call
subList(5, 7)
, although you are only using two elements, the entire list must stay in memory. With a copy, this is not the case, and all other elements can be freed.
You can read more about the exact same problem for strings: https://bugs.java.com/bugdatabase/view_bug?bug_id=4513622Thomas Martin
01/05/2024, 10:45 AM