Обзор работы с живыми данными - и еще одна причина полюбить Elixir

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

Всякий раз, когда данные постоянно обновляются в реальном времени, у вас есть поток. Это может быть что-то непрерывное, например музыка или видео. Это также может быть непрерывная серия обновлений данных в реальном времени, таких как лента Twitter или цены на акции. Это может быть даже набор координат мыши в пользовательском интерфейсе.

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

Предположим, у вас есть массив последних цен на акции Apple. Они могут дать вам представление о том, где была акция в последнее время, но на самом деле не ответят на вопрос, сколько вы заплатили бы, если бы купили 5 акций прямо сейчас. Если вы хотите указать самую последнюю цену, вам понадобится поток данных, обновляемых в реальном времени.

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

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

Еще одна оптимизация для работы с живыми данными - это ленивая оценка. Вместо того, чтобы делать потенциально дорогостоящие вычисления заранее, он ждет, чтобы увидеть, подходящее ли время. Так что при определенных обстоятельствах лень может быть полезным.

Если вы работаете на JavaScript, внешняя библиотека, такая как RxJS, предлагает удобные методы работы с потоками. В Elixir в язык встроена абстракция Stream.

Работа с потоками может ощущаться как работа с массивами. В JavaScript у вас есть функциональные методы для перебора массивов, например map и filter. У них есть аналоги в RxJS, которые предлагают преимущества разделения данных. Однако вам нужно добавить RxJS в свое приложение, чтобы воспользоваться этими преимуществами.

В Elixir у вас есть не массивы, а списки. На самом деле это связанные списки, которые по своей сути сильно отличаются от массивов. Они используются во многом так же, как массивы в других языках. Они являются разновидностью перечислителя.

Удобно, что и в потоках, и в списках Elixir можно использовать итераторы, такие как map и filter, предоставленныеEnum. Таким образом, работа с потоками в Elixir очень похожа на работу со списком или любым другим перечислителем, за исключением того, что он обеспечивает повышение эффективности при работе с большими или обновляемыми наборами данных.

Так почему бы просто не использовать потоки все время? В Elixir потоки определены как ленивые. Enum предоставляет функции итератора, которые по умолчанию активны, что означает, что они будут действовать сразу. В некоторых случаях это то, что вам нужно. Возможно, вы хотите получить ответ прямо сейчас и не ждете дополнительных данных. Эта ленивая оптимизация окупается только в том случае, если вы имеете дело с большими или бесконечными наборами данных.