Подтвердить что ты не робот

Когда следует использовать `withMutations` на карте в Immutable.js?

У меня есть серия мутаций, которые можно сделать на моей карте Immutable.js.

В какой момент я должен использовать withMutations вместо создания промежуточных неизменяемых карт?

Из документов Immutable.js:

Если вам нужно применить серию мутаций для создания нового неизменяемого Map, withMutations() создает временную изменяемую копию Карты, которая могут применять мутации в высокоэффективном режиме. На самом деле это как именно выполняются сложные мутации, такие как слияние.

Но где же линия? Если мне нужно сделать две мутации, я должен использовать withMutations?

4b9b3361

Ответ 1

Вы должны использовать withMutations, если хотите сгруппировать несколько изменений на объекте.

Поскольку каждое изменение создает клон, несколько изменений в строке вызывают несколько клонов. Используйте withMutations, чтобы применить несколько изменений, затем клонировать один раз в конце. Клон на каждом шаге означает, что вы читаете весь список для каждого изменения, что делает его n ^ 2. Использование изменяемой версии оставляет его только при N.

Это может привести к массивному результату, если вы просто начнете делать что-то волей-неволей, как предлагает другой ответ. Кикер это может не иметь значения при небольшом тестировании данных, но что произойдет, если вы нажмете его вживую, а затем выполните крупномасштабную операцию в массиве с 300 000 частями данных вместо тестовых данных, которые содержат только 100 элементов. В ваших тестовых данных вы сделали 10 000 копий, которых вы, возможно, не заметили. В производстве вы будете копировать 900 000 000,00 экземпляров, что может привести к выгоранию вашего компьютера (на самом деле, но вы бы заморозили вкладку).

Я написал демонстрацию, демонстрирующую разницу в производительности http://jsperf.com/with-out-mutatable

Ответ 2

Я также пытался решить, когда лучше использовать withMutations vs not. До сих пор я всегда использовал withMutations, когда мне нужно перебирать список элементов с неизвестным размером n и выполнять мутации n на одной карте. Пример:

updateItems(state, items) {
    return state.withMutations(state => {
        items.forEach(item => {
            state.set(item.get('id'), item);
         });
    });
}

То, что я хотел знать, - это если я должен использовать withMutations в меньшем известном наборе обновлений, или если я просто должен был бы цепочки set.

Пример:

setItems(state, items, paging) {
    return state.set('items', items).set('paging', paging);
}

Или:

setItems(state, items, paging) {
    return state.withMutations(state => {
        state.set('items', items);
        state.set('paging', paging);
    });
}

В этом случае я предпочел бы использовать первый вариант (цепочки set), но я не был уверен в влиянии производительности. Я создал этот jsPerf для проверки некоторых подобных случаев: http://jsperf.com/immutable-batch-updates-with-mutations.

Я запускал партии из 2 обновлений и 100 обновлений с использованием пустой исходной карты и сложной исходной карты, используя withMutations и просто цепочку set.

Результаты показывают, что withMutations всегда лучше в случае обновления 100, независимо от начальной карты. withMutations выполнялся незначительно лучше в 2 случаях обновления при запуске с пустой картой. Однако простое соединение 2 set вызовов выполняется лучше при запуске со сложной картой.

Ответ 3

Я бы просто создал промежуточные неизменяемые карты, а затем использовал некоторые инструменты профилирования, чтобы проверить, есть ли у вас какие-либо проблемы с производительностью с этим подходом. Не нужно выполнять оптимизацию производительности, прежде чем у вас возникнут проблемы с производительностью.

Как правило, я предпочитаю использовать существующие функции, такие как .map, .filter и т.д., не думая о withMutations. Если вам нужно создать новый список (или карту), в котором каждый элемент мутирован, я бы сначала задал вопрос о необходимости и попытался решить проблему, используя существующие инструменты и стиль функционального программирования. Если это невозможно, я бы создал пользовательскую мутацию с withMutations.