Будьте в спящем режиме HQL: как использовать комплекс, оставленный выборку соединения

Мемуализация обменивает время на пространство.

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

Классическим примером является вычисление последовательности Фибоначчи. Определение из учебника является рекуррентным соотношением:

F (n) = F (n-1) + F (n-2)

Реализовано наивно, похоже this:

int fib(int n) {
  if (n == 0) {
    return 0;
  }
  else if (n == 1) {
    return 1;
  }
  else {
    return fib(n-1) + fib(n-2);
  }
}

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

Реализованный с запоминанием, он выглядит следующим образом (неуклюже, но функционально):

int fib(int n) {
  static bool initialized = false;
  static std::vector<int> memo;

  if (!initialized) {
    memo.push_back(0);
    memo.push_back(1);
    initialized = true;
  }

  if (memo.size() > n) {
    return memo[n];
  }
  else {
    const int val = fib(n-1) + fib(n-2);
    memo.push_back(val);
    return val;
  }
}

Синхронизация этих двух реализаций на моем ноутбуке, для n = 42, наивная версия занимает 6,5 секунды. Записанная версия занимает 0,005 секунды (все системное время, то есть оно связано с вводом / выводом). При n = 50 запомненная версия по-прежнему занимает 0,005 секунды, а наивная версия, наконец, заканчивается через 5 минут & amp; 7 секунд (не говоря уже о том, что они оба переполнили 32-битное целое число).

9
задан Keren 8 November 2009 в 08:43
поделиться

1 ответ

Здесь есть несколько проблем:

  1. Ваш HQL в том виде, в котором вы его опубликовали, на самом деле не HQL :-) Это прямой SQL. Для HQL вам нужно использовать сопоставленные ассоциации для объединения таблиц. См. Улучшенную версию ниже.
  2. Насколько мне известно, предложение ON не поддерживает несколько условий соединения в скобках.
  3. NoSuchMethodError - это не то, что Hibernate выбрасывает :-) Скорее всего, у вас есть более старая версия antlr.jar где-то в пути к классам, и она выбирается вместо той, которую ожидает Hibernate. Найдите и удалите его.

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

select distinct t        
  from TASK t
  left join fetch t.server ser
  left join fetch ser.application app
  left join t.prompt p with p.applicationName in ('XXX')
 order by t.id

Обратите внимание, что приглашение не вызывается, потому что вы Можно' t использовать объединенную выборку вместе с с условием . Вы можете заменить его на выборку внутреннего соединения и , где , если ассоциация требуется.

Если у вас все еще возникают проблемы после решения проблемы пути к классам, не стесняйтесь опубликовать свой сопоставления, если вам нужна помощь с фактическим HQL.

28
ответ дан 4 December 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: