Обзор Envision с технической точки зрения


Главная » Ресурсы » Здесь

Envision — это доменный язык, адаптированный для прогнозирования и количественной оптимизации цепей поставок. Его синтаксис напоминает SQL и Python . Lokad предлагает облачные сервисы для разработки и выполнения сценариев. Входящие данные должны быть представлены в файлах с таблицами, либо в виде обычных текстовых документов, либо в виде таблиц Excel, загруженных в Lokad. Результатом выполнения сценария Envision является панель управления и, возможно, один или несколько итоговых файлов с таблицами, содержащих результаты вычислений по сценарию.

Создание доменного языка

Язык Envision появился в результате многолетнего опыта работы Lokad с сотнями компаний розничной торговли. Мы не планировали создавать его, когда только основали Lokad в 2008 году. Создание нового языка программирования — это сложная задача, и с 2008 по 2013 г. мы использовали только широко распространенные языки программирования. Однако позже, набравшись опыта, мы поняли, что разработав уникальный язык программирования, ориентированный на цепи поставок, мы бы смогли разрабатывать и выполнять задания от наших клиентов гораздо быстрее.

В 2014 году, когда команда Lokad начала использовать Envision для некоторых внутренних проектов, стало ясно, что проекты с использованием Envision систематически давали более высокие результаты, чем проекты на базе обычных языков программирования, даже если их создавали лучшие компании-разработчики ПО. Мы не говорим, что Envision лучше C#/Java/Python/SQL/и т. д. Дело в том, что в некоторых крайне специфических ситуациях, характерных для цепей поставок, эти языки не позволяют достигнуть наилучших результатов с точки зрения эффективности бизнеса (хотя в целом они замечательные).

Характеристики хорошо продуманного языка

Давайте смотреть правде в глаза: абсолютное большинство языков программирования "для бизнеса" на самом деле можно охарактеризовать как "практически бесполезные". При создании Envision мы решили сделать отличный язык программирования, ограниченный лишь сферой применения — цепями поставок.

Язык:

  • Никаких циклов, никаких ветвлений (в этом и заключается его особенность)
  • Строгая типизация
  • Вызовы функции не имеют побочных эффектов
  • Собственная компиляция кода
  • Молниеносное выполнение за счет специализированных алгоритмов

Среда разработки:

  • Выделение кода цветом и автоматическое завершение кода
  • Интеллектуальный компилятор, выдающий осмысленные сообщения об ошибках
  • Полный контроль версий для проводимых правок и запусков
  • Контекстуальный обзор входящих данных

С точки зрения стиля кодировки, Envision во многом опирается на сжатый синтаксис Python, однако мы взяли некоторые эффективные решения из других языков, таких как C#.

SQL и Envision

Как SQL, так и Envision имеют сильную привязку к данным. Однако если SQL запрашивает модели данных транзакций, уделяя особое внимание параметрам ACID (атомарность, непротиворечивость, изолированность, долговечность), Envision запрашивает лишь набор табличных файлов. В самом деле, если говорить о большинстве задач по оптимизации цепей поставок, "текущие" данные не нужны, требуются лишь данные, полученные вчера или ранее. Эти данные являются историческими и неизменными. В результате, такие файлы можно обрабатывать в десятки раз быстрее (1), чем реляционные таблицы, потому что в них нет таких операций как INSERT, UPDATE или DELETE — только READ.

Envision может отображать таблицу с оператором, который очень похож на оператор SELECT, используемый в SQL.
show table "Product List" with
  Id
  Name
  Supplier
Опытные пользователи SQL наверняка сразу заметят, что в данной строке отсутствует оператор FROM, который обычно используется после SELECT. Мы заметили, что в цепях поставок практически все данные так или иначе связаны с товарами (или SKU) и что практически все исторические данные могут быть описаны как события, привязанные к товарам. Таким образом, Envision использует "естественные" объединения, и в нем не требуется повсюду прописывать алгоритмы JOIN для получения одних и тех же схем. Для примера, в сегментах кода, приведенных ниже, показано, как можно составить список самых продаваемых товаров на основе истории продаж без прописывания объединений.
end := max(date)
// O — заказы
LastYearQty = sum(O.Qty) when date > end - 365
show table "Top Sellers" with
  Id
  Name
  LastYearQty
  order by LastYearQty desc
Кроме того, мы заметили, что в цепях поставок очень часто происходит объединение данных по календарным периодам. Менеджерам необходимо получать данные за день, неделю или месяц. Несмотря на то, что эта потребность является рутинной, в SQL очень сложно составить недельный график, который в Envision создается с помощью двух "простейших" строк кода.
Week.quantity := sum(O.Qty)
show linechart "Weekly quantities sold" with
  Week.quantity
Наконец, средства SQL работают по модели один запрос за единицу времени. Мы считаем, что для эффективного использования панели управления обычно требуется целый набор очень специфических коммерческих показателей. Таким образом, язык Envision изначально предполагает создание сложных панелей управления за один раз.

(1) Да, базы данных SQL можно настроить таким образом, чтобы их производительность была такой же высокой, как при работе с простыми файлами, однако мы считаем, что усилия, которые для этого необходимо приложить, сводят на нет преимущества, ради которых и создавались базы данных SQL.

Excel и Envision

Envision — это язык программирования, однако он создавался таким образом, чтобы продвинутые пользователи Excel могли легко работать с ним. Мы, ни в коем случае, не принижаем достоинства Excel: очень сложно превзойти его проверенные временем листы с таблицами, и будучи специалистами по обработке данных и разработчиками ПО, мы часто сами используем Excel, например, для быстрого обзора результатов серии экспериментов.

Одно из основных преимуществ Excel — возможность быстрой обработки целых рядов или столбцов данных, то есть векторные вычисления, выполняемые с помощью операций вырезания и вставки. Векторные вычисления очень полезны, чего нельзя сказать об алгоритме вырезания и вставки. Предположим, нам нужно рассчитать среднюю цену продукции за прошлый год на основе проведенных операций. В Envision для этого потребуется прописать несколько строк кода.
O.UnitPrice = O.NetAmount / O.Qty
end := max(date)
UnitPrice = mode(O.UnitPrice) when date > end - 365
show table "Median Price" with median(UnitPrice)
Первая строка — это эквивалент добавлению нового столбца с именем UnitPrice в таблицу O (Заказы) для векторных вычислений. Третья строка также связана с векторными вычислениями, где mode (наиболее часто встречающееся значение) рассчитывается для каждого товара. Как и в Excel, в Envision очень просто добавлять промежуточные вычисления и затем объединять их.

Envision также уделяет большое внимание компактности панелей управления, во многом как в синтетических листах Excel. Все операторы show в Envision задают объекты, которые необходимо отобразить в панели управления, и все эти объекты выравниваются по сетке, подобной той, которая используется в Excel.
show label "Hello World" a1d1 tomato
show table "Product Lines" a2b2 royalblue with
  sum(1)
show table "Order Lines" c2b2 darkorange with
  sum(O.1)
В сценарии, показанном выше, задано три объекта, расположенных соответственно в ячейках A1:D1, A2:B2, и C2:D2 в соответствии с системой Excel, где буквами обозначаются столбцы, а цифрами — строки.

Никаких циклов, никаких ветвлений и многое другое

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

Давайте попробуем рассчитать общий объем продаж 10 самых продаваемых товаров за каждую неделю этого года и сравнить эти недельные показатели с такими же показателями для тех же товаров в прошлом году. Для этого потребуется прописать несколько строк кода, показанных ниже.
end := max(date)
Vol = sum(O.Qty) when date > end - 365
Week.amt := sum(O.Qty) where rank() sort [Vol] <= 10
show linechart "Top 10" a1f3 tomato unit: "$" with 
  Week.amt as "Sold this year"
  Week.amt[-52] as "Sold last year"
Кроме того, Envision работает быстро, очень быстро. Мы не только смогли упростить многие доменные алгоритмы (2), но и поместить в кэш (почти) все узлы расчета наших сценариев Envision. В результате, когда слегка измененные сценарии выполняются еще раз, заново рассчитываются только те узлы расчета, которые были изменены. На практике, как только вы в первый раз обработаете 20 Гб данных за 5 секунд, вы не захотите возвращаться к медленным запросам SQL.

(2) Мы используем алгоритм блочной сортировки, которая зачастую превосходит более привычную быструю сортировку в 500 раз. Несмотря на то, что теоретически оптимальное ограничение алгоритмов сортировки составляет O(n.log(n)), ускорение сортировки в 500 раз возможно в некоторых ситуациях (например, при сортировке по датам). Ситуации в цепях поставок очень часто бывают благоприятными в этом отношении.