immer
immer copied to clipboard
Array update speed
🐛 Bug Report
I thought that since immer updates arrays directly, it would be more or less as performant as updating the array directly, but this is not at all the case.
I simulated the pattern "remove the nth element of an array". Code pasted later. The results on my machine are:
filter: 186.852ms
immer: 15.871s
splice: 50.453ms
immer seems to be 84 slower than the standard way to remove the nth element of an array in a mutable way (which is looping throught all the elements to remove the given index). This, itself, is not an efficient method, yet in my example is only ~4 times slower then directly using Array.splice()
Link to repro
import {produce} from "immer"
const arr = Array.from({length: 10_000_000}, (i, idx) => ({n: idx}));
console.time('filter');
let remove10_000nth = arr.filter(((i, idx) => idx !== 10_000));
console.timeEnd('filter');
console.time('immer');
remove10_000nth = produce(arr, draft => {
draft.splice(10_000, 1)
})
console.timeEnd('immer');
console.time('splice');
arr.splice(10_000, 1);
console.timeEnd('splice');
Environment
- Immer version: 10.0.4
- [x] I filed this report against the latest version of Immer
- [ ] Occurs with
setUseProxies(true) - [ ] Occurs with
setUseProxies(false)(ES5 only)
Note that Immer also deeply freezes the output, so that is probably a large portion of your cost here. Might want to play with disabling that, or freezing arr and the elements inside it first.
On Wed, Apr 17, 2024 at 10:23 AM pistacchio @.***> wrote:
🐛 Bug Report
I thought that since immer updates arrays directly, it would be more or less as performant as updating the array directly, but this is not at all the case.
I simulated the pattern "remove the nth element of an array". Code pasted later. The results on my machine are:
filter: 186.852ms immer: 15.871s splice: 50.453ms
immer seems to be 84 slower than the standard way to remove the nth element of an array in a mutable way (which is looping throught all the elements to remove the given index). This, itself, is not an efficient method, yet in my example is only ~4 times slower then directly using Array.splice() Link to repro
import {produce} from "immer" const arr = Array.from({length: 10_000_000}, (i, idx) => ({n: idx})); console.time('filter');let remove10_000nth = arr.filter(((i, idx) => idx !== 10_000));console.timeEnd('filter'); console.time('immer');remove10_000nth = produce(arr, draft => { draft.splice(10_000, 1)})console.timeEnd('immer'); console.time('splice');arr.splice(10_000, 1);console.timeEnd('splice');
Environment
- Immer version: 10.0.4
- I filed this report against the latest version of Immer
- Occurs with setUseProxies(true)
- Occurs with setUseProxies(false) (ES5 only)
— Reply to this email directly, view it on GitHub https://github.com/immerjs/immer/issues/1117, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAN4NBDAET3ZSVAKMIFCNEDY5YWRZAVCNFSM6AAAAABGK2G46WVHI2DSMVQWIX3LMV43ASLTON2WKOZSGI2DONRYHAZDEMY . You are receiving this because you are subscribed to this thread.Message ID: @.***>