La razón de que código particular es lento porque se está trabajando en primitivas, pero se trata de utilizar las operaciones genéricas, por lo que las primitivas tienen que ser en caja. (Esto podría mejorarse si List
y sus antepasados estuvieran especializados.) Esto probablemente reducirá la velocidad de un factor de 5 o menos.
Además, algorítmicamente, esas operaciones son algo costosas, porque se hace una lista completa, y luego se crea una lista completamente nueva descartando algunos componentes de la lista intermedia. Si lo hicieras de una vez, estarías mejor. Se podría hacer algo como:
list collect (case e if (e*2>10) => e*2)
pero lo que si el cálculo e*2
es muy caro? Entonces podría
(List[Int]() /: list)((ls,e) => { val x = e*2; if (x>10) x :: ls else ls }
excepto que esto parecería al revés. (Podría revertirlo si fuera necesario, pero eso requiere crear una nueva lista, que de nuevo no es ideal algorítmicamente).
Por supuesto, tiene el mismo tipo de problemas algorítmicos en Java si está utilizando un solo lista enlazada: su nueva lista terminará hacia atrás, o tendrá que crearla dos veces, primero en reversa y luego hacia adelante, o debe compilarla con recursividad (sin cola) (lo cual es fácil en Scala, pero desaconsejable para este tipo de cosas en cualquier idioma, ya que se agotará la pila), o tiene que crear una lista mutable y luego pretender que no es mutable. (Lo cual, por cierto, también puede hacer en Scala - consulte mutable.LinkedList
.)
Esta respuesta tiene el problema, pero no ofrece una buena solución. – Raphael
@Raphael - Realmente no hay uno dado el estado actual de la biblioteca. 'view' /' force' no te va a salvar cuando trabajas con primitivos. –
Si 'e * 2' fuera costoso, entonces el costo de tener el paso intermedio disminuiría. Quizás problemas de memoria, si manejas grandes cantidades de datos. – ziggystar