Что является более эффективным - вычисление результатов с использованием функции в реальном времени или чтение результатов непосредственно из базы данных? - PullRequest
3 голосов
/ 02 марта 2012

Давайте возьмем такой пример сценария:

Существует сложная функция действительно , которая включает математические квадратные корни и кубические корни (которые обрабатываются медленнее) для вычисления выходных данных.В качестве примера, давайте предположим, что функция принимает два параметра a и b , а диапазон ввода для значений a и b четко определен .Предположим, что входные значения a и b могут находиться в диапазоне от 0 до 100.

Таким образом, по существу fn (a, b) может бытьлибо рассчитывается в режиме реального времени, либо его результаты могут быть предварительно заполнены в базе данных и извлечены по мере необходимости.

Метод 1: Вычислить в реальном времени

function fn(a,b){

result = compute_using_cuberoots(a,b)

return result
}

Метод 2: Получить результат функции из базы данных

У нас есть база данных, предварительно заполненная входными значениями, сопоставленными с соответствующим результатом:

a   |  b  | result
0   |  0  |   12.4
1   |  0  |   14.8
2   |  0  |   18.6
.   |  .  |    .
.   |  .  |    .
100 | 100 |  1230.1

И мыcan

function fn(a,b){

result = fetch_from_db(a,b)

return result
}

Мой вопрос:

Какой метод вы бы поддержали и почему?Как вы думаете, почему один метод более эффективен, чем другой?

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

Спасибо.

Фон вопроса (может быть не актуально)

Пример: В таких сценариях, как обработка изображений,чаще можно встретить такие ситуации, когда диапазон значений для входных данных (R, G, B) известен (0-255), а математические вычисления для квадратных и кубических корней вводят слишком много времени длязапросы к серверу должны быть выполнены.

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

Следовательно, необходимо выбрать один из методов, описанных выше, который также будет наиболее оптимальным в таких ситуациях.

Подробнее о моей ситуации ( при необходимости ):

Framework: Ruby on Rails, База данных: MongodB

Ответы [ 5 ]

3 голосов
/ 02 марта 2012

Я бы не защищал ни один из этих методов, я бы протестировал их оба (если бы я думал, что они оба разумны) и получил бы некоторые данные.

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

2 голосов
/ 02 марта 2012

«Более эффективный» - нечеткий термин. «Быстрее» конкретнее.

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

Чтобы сделать «ускорение» чуть менее конкретным, когда вы говорите о взаимодействии с пользователем и в определенных пределах, фактическая скорость менее важна, чем кажущаяся скорость. Правильная обратная связь в нужное время заставляет людей либо чувствовать, что все идет быстро, либо, по крайней мере, заставляет их чувствовать, что ждать немного - это не большое дело. Подробную информацию о том, как это сделать, можно найти в User Experience в сети Stack Exchange.

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

Вам, вероятно, следует провести тестирование в течение длительного периода времени. Я ожидаю, что будет больше вариация в скорости от дБм. Хотя я не знаю, какой вариации вы должны ожидать.

2 голосов
/ 02 марта 2012

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

«Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла» Дональд Кнут

0 голосов
/ 02 марта 2012

Я бы подумал о сохранении значений в самом коде:

class MyCalc
  RESULTS = [
    [12.4, 14.8, 18.6, ...]
    ...
    [..., 1230.1]
  ]
  def self.fn a, b
    RESULTS[a][b]
  end
end

MyCalc.fn(0,1)         #=> 14.8
0 голосов
/ 02 марта 2012

Я бы хотел использовать хеш как комбинацию вычисления и хранения. С ним действительно сложная функция представлена ​​как a**b:

lazy = Hash.new{|h,(a,b)|h[[a,b]] = a**b}
lazy[[4,4]]
p lazy #=> {[4, 4]=>256}
...