Kotlin encadena el performance de las funciones de colección

Soy nuevo en Kotlin y estoy aprendiendo el idioma resolviendo rompecabezas simples en IntelliJ, usando los consejos presentados por el IDE. Escribí este fragment de código (Encontrar el número más repetido):

fun main(args: Array<String>) { val tracer = mutableMapOf<Int,Int>() var currentMaxCount = 0 val numbers = readLine()!!.split(' ').map(String :: toInt) for(number in numbers) { val currentCountOfNum = incrementAndGetCurrentCountOf(number, tracer) currentMaxCount = if(currentCountOfNum > currentMaxCount) currentCountOfNum else currentMaxCount } println(currentMaxCount) } fun incrementAndGetCurrentCountOf(num : Int, tracer: MutableMap<Int,Int>) = if(tracer[num] == null) { tracer.put(num, 1) 1 } else { val newCount = tracer[num]!! + 1 tracer.put(num, newCount) newCount } 

Y el IDE sugirió que el siguiente código:

  var currentMaxCount = 0 for(number in numbers) { val currentCountOfNum = incrementAndGetCurrentCountOf(number, tracer) currentMaxCount = if(currentCountOfNum > currentMaxCount) currentCountOfNum else currentMaxCount } 

ser cambiado a esto:

 val currentMaxCount = numbers .map { incrementAndGetCurrentCountOf(it, tracer) } .max() ?: 0 

Entiendo lo que está sucediendo. Pero me preguntaba si el performance se convertiría en O (2n) si uso la sugerencia del IDE. Es O (n) en lo que se me ocurrió. Sé que teóricamente no hace la diferencia, pero me gustaría saber si Kotlin usa magia para mantener el time de ejecución en O (n). (Cualquier sugerencia adicional para networkingucir aún más el código es bienvenido)

TL; DR

Sí, hay un impacto en el performance porque son en realidad dos iteraciones separadas.

En este context particular, puede evitar hacer la iteración adicional aprovechando un método dedicado maxBy :

 numbers.maxBy { incrementAndGetCurrentCountOf(it, tracer) } ?: 0 

Es importante recordar que las collections de Kotlin, a diferencia de las secuencias de Java, no son flojas y todos esos methods sofisticados encapsulan implementaciones imperativas simples.

Por lo tanto, las llamadas de map encadenadas M dan como resultado O (M * N) en el caso optimista, incluso si todo el procesamiento podría cortocircuitarse porque no es necesario visitar todos los elementos:

 listOf(1, 2, 3) .map { println(it) }.first() 

esto imprime:

 1 2 3 

En tales situaciones, es importante recordar acerca de la existencia del método asSequence que crea una secuencia evaluada de forma perezosa respaldada por una colección determinada:

 listOf(1, 2, 3).asSequence() .map { println(it) }.first() 

que imprime:

 1 
  • Excepción causada por: java.lang.ClassNotFoundException: org.reactivestreams.Publisher
  • Propiedad de superclass no inicializada en class Derivada
  • Android Dagger 2.11 con Kotlin, problema de publicación de ContributesAndroidInjector
  • post no recibido en el chat de Bluetooth. ¿Está roto mi controller?
  • El @Rule> debe ser público ValidationError en Kotlin Junit test
  • Llamando a un método con param nulo
  • Kotlin, JPA y campos booleans
  • Tipo no coincidente: ¿tipo inferido es Cadena? pero se esperaba String en kotlin
  • Los datos de Google Fit no leen desde la nube, solo leen localmente
  • Por qué Kotlin funciona con los parameters pnetworkingeterminados crea un método con parámetro no utilizado
  • ¿Por qué IntelliJ no reconoce mi método principal?