¿Cuándo debo usar `withMutations` en un mapa en Immutable.js?
(3)
Tengo una serie de mutaciones que hacer en mi mapa Immutable.js.
¿En qué momento debería preferir usar withMutations
lugar de crear mapas intermedios inmutables?
De los documentos de Immutable.js:
Si necesita aplicar una serie de mutaciones para producir un nuevo Mapa inmutable, withMutations () crea una copia mutable temporal del Mapa que puede aplicar mutaciones de una manera altamente eficaz. De hecho, esto es exactamente cómo se hacen las mutaciones complejas como la fusión.
Pero, ¿dónde está la línea? Si necesito hacer dos mutaciones, ¿debo usar withMutations
?
Debe usar withMutations cuando desee agrupar varios cambios en un objeto.
Debido a que cada cambio crea un clon, varios cambios en una fila causan varios clones. Use withMutations para aplicar varios cambios y luego clone una vez al final. Un clon en cada paso significa que está leyendo la lista completa de cada cambio, lo que hace que sea una operación n ^ 2. Usar la versión mutatable lo deja solo en N.
Esto puede crear un gran impacto en el rendimiento si simplemente empiezas a hacer las cosas casi nunca como sugiere la otra respuesta. Lo bueno es que puede que no importe en una pequeña prueba de datos, pero qué sucede si lo transmite en vivo y luego realiza una operación a gran escala en una matriz con 300,000 datos en lugar de sus datos de prueba que solo tienen 100 elementos. En tus datos de prueba, hiciste 10,000 copias de las cuales podrías no notar. En producción harías 900,000,000,00 copias que podrían encender tu computadora (no realmente, pero congelarías la pestaña).
Escribí una demostración que demuestra la diferencia de rendimiento http://jsperf.com/with-out-mutatable
Simplemente crearía mapas inmutables intermedios y luego utilizaría algunas herramientas de perfil para verificar si realmente tiene algún problema de rendimiento con ese enfoque. No es necesario realizar optimizaciones de rendimiento antes de tener problemas de rendimiento.
Como regla general, prefiero usar las funcionalidades existentes como .map
, .filter
, etc., sin pensar en las withMutations
. Si hay una necesidad de crear una nueva Lista (o Mapa) donde se muta cada elemento, primero cuestionaría esa necesidad y trataré de resolver el problema utilizando las herramientas existentes y el estilo de programación funcional. Si eso es imposible, crearía una mutación personalizada con withMutations
.
También he estado tratando de decidir cuándo es mejor usar withMutations vs no. Hasta ahora siempre he usado withMutations cuando necesito recorrer una lista de elementos con un tamaño desconocido n
, y realizar n
mutaciones en un solo mapa. Ejemplo:
updateItems(state, items) {
return state.withMutations(state => {
items.forEach(item => {
state.set(item.get(''id''), item);
});
});
}
Lo que quería saber es si debo usar withMutations en un conjunto de actualizaciones conocido más pequeño, o si debo set
cadena.
Ejemplo:
setItems(state, items, paging) {
return state.set(''items'', items).set(''paging'', paging);
}
O:
setItems(state, items, paging) {
return state.withMutations(state => {
state.set(''items'', items);
state.set(''paging'', paging);
});
}
En este caso, preferiría usar la primera opción (llamadas de set
encadenados), pero no estaba seguro del impacto en el rendimiento. Creé este jsPerf para probar algunos casos similares: http://jsperf.com/immutable-batch-updates-with-mutations .
Ejecuté lotes de 2 actualizaciones y 100 actualizaciones, usando un mapa inicial vacío, y un mapa inicial complejo, usando ambas con withMutations
y solo un set
withMutations
.
Los resultados parecen mostrar que withMutations
siempre fue mejor en el caso de 100 actualizaciones, independientemente del mapa inicial. withMutations
funcionó ligeramente mejor en el caso de 2 actualizaciones al comenzar con un mapa vacío. Sin embargo, solo el encadenamiento de 2 llamadas de set
funcionó mejor al comenzar con un mapa complejo.