Recibí un mensaje de pelusa mientras escribía Kotlin usando IntelliJ como mi IDE: The argument can be converted to 'Set' to improve performance
Mi código fue algo como esto:
val variable3 = variable1 - variable2 variables son de tipo List<Int>
El linter me recomendó cambiarlo a val variable3 = variable1 - variable2.toSet()
Me gustaría saber por qué recomienda este cambio y dónde está la documentación para que la próxima vez pueda buscar los mensajes y aprender el razonamiento detrás de la verificación de pelusa.
Se trata de rendimiento y eficiencia, en particular, de cómo se escala el rendimiento a medida que sus datos crecen.
El operador - llama a la función de extensión Iterable<T>.minus(elements: Iterable<T>) de la biblioteca estándar. Si observa su código (lo que puede hacer en IntelliJ), verá que funciona tomando el primer iterable ( variable1 en este caso) y filtrándolo para mantener solo los valores que no están en el segundo ( variable2 ).
¿Cómo comprueba si un elemento está en el segundo? Llamando a su método contains() . Pero cómo funciona eso dependerá del tipo de iterable. La mayoría de los Set , por ejemplo, pueden buscar por código hash, lo que lleva poco tiempo, independientemente del tamaño del conjunto.
Sin embargo, la mayoría de List s y otros iterables no pueden hacer eso: necesitan buscar en toda la lista, elemento por elemento. Obviamente, el tiempo que tarde dependerá del tamaño de la lista: será muy rápido para las listas cortas, pero puede llevar algo de tiempo buscar en una lista con miles o millones de elementos.
Lo que lo hace particularmente importante en este caso es que tiene que hacer esa búsqueda repetidamente: una vez por cada elemento del primero. Así que el tiempo realmente puede acumularse.
Digamos que el primer iterable tiene 𝐌 elementos y el segundo tiene 𝐍. La resta tiene que hacer 𝐌 comprobaciones; si el segundo es un conjunto, entonces cada comprobación lleva aproximadamente el mismo tiempo, por lo que el tiempo total es proporcional a 𝐌. Pero si no, entonces cada verificación tomará un tiempo proporcional a 𝐍, por lo que el tiempo total es 𝐌×𝐍, ¡que puede crecer mucho muy rápido! (Por ejemplo, si hace que cada lista sea 10 veces más grande, tardará 100 veces más).
Entonces, si no desea que su programa se detenga cuando comience a manejar más datos, puede valer la pena convertir primero la segunda lista en un conjunto. Para pequeñas cantidades de datos, agrega un poco de trabajo adicional, pero eso probablemente no se notará; y para grandes cantidades de datos, puede ser una gran victoria.
Es por eso que la inspección de IntelliJ lo sugiere.
(Para aquellos de ustedes que saben sobre la complejidad algorítmica, perdonen las simplificaciones que he hecho aquí :)
Curiosamente, cuando lo probé yo mismo (en IntelliJ 2021.2.3 con Kotlin v1.5.73), no hizo esa sugerencia. Y mirando esa implementación de la biblioteca estándar, ¡veo que en algunos casos el método minus() hará la conversión por usted! Sin embargo, creo que no cubre algunos otros casos comunes, por lo que vale la pena hacer la conversión usted mismo si cree que las listas podrían aumentar.
Puede pasar el cursor y abrir la documentación de esta manera: 
Las opciones generales de solución rápida se pueden encontrar y activar/desactivar en configuración -> inspecciones -> kotlin (ejemplo)