Самый быстрый способ обработать (большой) массив с общим объектом? [Node.js / worker_threads / GPU.js] - PullRequest
0 голосов
/ 11 марта 2020

Проблема

В бэкэнд-приложении Node.js я добавляю матрицу (массив) со всеми возможными комбинациями культур и полей фермы. Таким образом, эта матрица содержит все теоретически возможные варианты выращивания сельскохозяйственных культур, которые есть на ферме. Для каждого варианта выращивания мне необходимо рассчитать ожидаемый урожай, доход и потенциальные предупреждения (например, «Выращивание рапса после сахарной свеклы не рекомендуется из-за повышения давления нематод»), среди прочих.

Вы можете найти упрощенный код макета моего текущего решения ниже. Как описано ранее, массив всех комбинаций создается первым. Затем на втором этапе оценивается каждый растущий вариант (элемент массива) (см. Класс GrowingOption). Объект store играет здесь центральную роль: в store данные о каждом поле и урожае хранятся и имеют внутренние ссылки (циклические ссылки). Эти данные необходимы для расчета ожидаемой доходности, дохода и предупреждений для каждого варианта роста.

Текущий код работает как есть. Однако, особенно для больших ферм (=> больших массивов,> 100 000 записей), для оценки матрицы обычно требуется 10 секунд (на сервере) или даже больше (в зависимости от параметров). То, что я ищу, это ускорить этот процесс, в идеале без полного переписывания бэкэнда (структура в основном развивается вокруг концепции центрального store объекта).

Упрощенный код макета:

const { predictYield, predictRevenue, checkWarnings } = require('./external_module')

const array = [
  ['corn', 'field1'],
  ['wheat', 'field1'],
  ['barley', 'field1'],
  // ... 100,000 other entries
  ['soy bean', 'field10000']
]

const class GrowingOption {
  constructor(crop,field,store) {
    this.crop = crop
    this.field = field
    this.yieldEstimate = predictYield(crop,field,store)
    this.revenueEstimate = predictRevenue(crop,field,store)
    this.warnings = checkWarnings(crop,field,store) // array of strings or []
    // etc.
  }
}

const growingOptions = array.map(
      combination => new GrowingOption(combination[0], combination[1], store)
    )

То, что я пробовал до сих пор

Я пытался настроить этот раздел кода для запуска многопоточности, используя Napa. js. Тем не менее, я быстро столкнулся с проблемой того, что мой объект магазина не был сериализуемым (из-за его круговой структуры), что вызвало исключение в Napa. js. Затем я начал читать о том, как разделить объект store между рабочими ( см. Эту проблему ), хотя казалось, что я не могу преобразовать свой существующий объект хранилища в транспортабельный .

Еще одна вещь, которую я попробовал, состояла в том, чтобы привести в соответствие store, используя flatted , а затем передать все это Напе. js. Скажем так, делая это, я также мог запустить бэкэнд на Raspberry Pi, используя свой текущий подход ...

Я также взглянул на woker_threads и GPU. js. Поскольку у меня нет опыта работы ни с одним из них, я решил спросить мнения и советы, прежде чем углубляться в любой из этих вариантов.

Спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...