Визуализация данных ImmutableJS из хранилища Redux в виде графика

Я работаю над приложением React и Redux, которое использует ImmutableJS для хранения всего своего состояния. Приложение получает данные от датчика с частотой около 100 Гц. Мне нужно нарисовать график, который обновляется в реальном времени и отображает эти данные. Я использовал React-Vis для графика, проблема в том, что он принимает массив объектов, а не структуру данных ImmutableJS.

Я решил это, преобразовав структуру данных ImmutableJS в такой массив:

const data = this.props.HEGPercentage.toIndexedSeq().toArray()

Это работает, но проблема, с которой я сталкиваюсь, заключается в огромном отставании, если я запускаю это с реальными данными, я думаю, потому что он должен все время создавать новый массив.

Как я могу создать для этого высокопроизводительное решение и при этом использовать ImmutableJS?


person Magnus Brantheim    schedule 18.09.2017    source источник
comment
Похоже, вы отправляете 100 действий по изменению состояния в секунду. Я бы подумал, что это может значительно замедлить работу само по себе, даже без огромных дополнительных накладных расходов, связанных с фактической попыткой повторного рендеринга графика с этими данными со скоростью 100 кадров в секунду. Не уверен, что использование toIndexedSeq().toArray() является проблемой. Если вы пропустите график и просто сделаете что-то простое, например console.log(this.props.HEGPercentage). Это по-прежнему вызывает отставание страницы (затрудняет прокрутку, ввод в поля ввода и т. д.)? Просто пытаюсь установить, стоит ли пытаться оптимизировать toIndexedSeq().toArray().   -  person jonahe    schedule 18.09.2017
comment
У меня есть некоторый код для имитации ввода данных датчика и установки скорости, которая должна быть одинаковой, и не было задержек. Теперь я также провел рефакторинг редьюсера, чтобы использовать обычные объекты JS вместо неизменяемых, и, похоже, это значительно улучшило производительность. Я все же хотел бы использовать Immutable, если это возможно, для согласованности с остальной частью приложения...   -  person Magnus Brantheim    schedule 18.09.2017
comment
В порядке. Действительно ли данные датчика настолько точны (или колебания настолько велики), что значения почти никогда не появляются снова? Если нет, возможно, можно было бы оптимизировать через какое-то кеширование. Если значения излишне точны (возможно, разрешение экрана в любом случае не может отображать разницу между 0,00001 и 0,00002), возможно, входные данные можно округлить, чтобы значения не менялись так часто (меньше повторных рендерингов) и повторялись чаще. (лучше для кэширования). Возможно, посмотрите на github.com/reactjs/reselect.   -  person jonahe    schedule 18.09.2017
comment
В противном случае я не знаю. Кажется, вам придется рано или поздно сделать перевод из Immutable js в массив (если это то, что графическая библиотека хочет в качестве входных данных). Однако я должен сказать, что ни производительность, ни Immutable.js не являются чем-то, в чем я являюсь экспертом. Так что да… читайте мой совет как чистую спекуляцию.   -  person jonahe    schedule 18.09.2017
comment
Я использую селекторы. Я могу попробовать округление и посмотреть, поможет ли это. Сделали бы вы округление перед тем, как сохранить его в магазине Redux? На данный момент он обычно имеет около 13 знаков после запятой, которые могут быть ненужными. Я также реализовал усреднение, поэтому он принимает 10 значений датчиков, усредняет их, а затем сохраняет их, что сокращает обновления примерно до 10 Гц.   -  person Magnus Brantheim    schedule 18.09.2017
comment
Хороший вопрос. Я на самом деле не знаю. Я бы, наверное, начал с попытки сделать это перед сохранением, да. Но я начинаю задаваться вопросом, подходит ли для этого Redux. Важно ли иметь историю всех этих действий и т.д.? Потому что в противном случае это больше похоже на проблему, подходящую для rx.js или одной из этих реактивных библиотек. Эта часть программы представляет собой поток преобразований непрерывного потока данных. У вас есть источник потока, предоставляющий данные датчиков, вы группируете точки данных по 10, выполняете усреднение, а затем обновляете представление.   -  person jonahe    schedule 18.09.2017
comment
(Но я также вижу аргумент в пользу того, чтобы не создавать новую библиотеку только для этого.)   -  person jonahe    schedule 18.09.2017


Ответы (1)


Преобразование между простыми объектами JS и объектами Immutable.js может быть очень дорогим. В частности, операции fromJS() и toJS() являются самыми затратными операциями в библиотеке Immutable.js, и их следует по возможности избегать (и особенно в функциях Redux mapState).

Похоже, вы уже хоть немного на правильном пути. Используйте запоминаемые селекторы, чтобы сократить дорогостоящие преобразования, постарайтесь округлить эти числа, если это возможно, чтобы было меньше бессмысленных изменений, и сократите общее количество обновлений в целом.

В моем списке ссылок React/Redux есть большой раздел статей о повышение производительности для React, Redux и Immutable.js, что может быть полезно.

Также стоит отметить, что я лично не рекомендую использовать Immutable .js по разным причинам.

person markerikson    schedule 18.09.2017
comment
Хорошо, после прочтения некоторых статей, на которые вы ссылались, я думаю, что склоняюсь к удалению Immutable.js из проекта, поскольку одной из основных задач приложения является рисование графика в реальном времени, и это, похоже, требует преобразования в объект JS. . Теперь я думаю о том, должен ли я просто изменить массив. Я использую concat каждый раз, когда добавляю значение, но, насколько я знаю, это создает новый массив, который кажется немного расточительным. Меня больше всего беспокоит рендеринг данных датчиков в режиме реального времени, желательно максимально быстрый и точный. - person Magnus Brantheim; 19.09.2017
comment
Если вы используете React-Redux, то он полагается на неизменяемые обновления для создания новых ссылок, чтобы он мог обнаруживать изменения и повторно отображать. Если вы не используете React-Redux, это может не беспокоить. Тем не менее, я бы все же пошел дальше и попытался сначала сделать это правильно, а потом посмотреть, как все работает. - person markerikson; 19.09.2017