Может кто-нибудь, пожалуйста, продемонстрируйте для меня более эффективный алгоритм декартова продукта, чем тот, который я использую в настоящее время (при условии, что он есть). Я огляделся вокруг и немного искал, но не вижу ничего очевидного, поэтому я мог бы что-то упустить.
foreach (int i in is) {
foreach (int j in js) {
//Pair i and j
}
}
Это очень упрощенная версия того, что я делаю в своем коде. Два целых числа - это ключи поиска, которые используются для извлечения одного или нескольких объектов, и все объекты из двух поисков соединены вместе в новые объекты.
Этот небольшой блок кода в гораздо более сложной системе становится основным узким местом производительности, поскольку набор данных, который он использует, масштабируется. Некоторое из этого, вероятно, можно было бы смягчить, улучшив структуры данных, используемые для хранения объектов и поисковых запросов, но основная проблема, которую я чувствую, по-прежнему является вычислением самого декартового произведения.
Изменить
Итак, еще один пример моего конкретного использования алгоритма, чтобы узнать, могут ли быть какие-либо трюки, которые я могу использовать в ответ на комментарий Marc. Общая система - это механизм запросов SPARQL, который обрабатывает запросы SPARQL по наборам данных Graph, SPARQL - это язык, основанный на шаблонах, поэтому каждый запрос состоит из серии шаблонов, сопоставленных с графиком. В случае, когда два последующих шаблона не имеют общих переменных (они не пересекаются), необходимо вычислить декартово произведение решений, созданных двумя шаблонами, чтобы получить набор возможных решений для общего запроса. Может быть любое количество шаблонов, и мне, возможно, придется вычислять декартовы произведения несколько раз, что может привести к довольно экспоненциальному расширению возможных решений, если запрос состоит из серии непересекающихся паттернов.
Как-то из существующих ответов я сомневаюсь, есть ли какие-либо трюки, которые могут применяться
Обновление
Итак, я думал, что опубликую обновление о том, что я реализовал, чтобы свести к минимуму необходимость делать декартовы продукты и, таким образом, оптимизировать механизм запросов вообще. Обратите внимание, что не всегда возможно полностью устранить необходимость в продуктах, но почти всегда можно оптимизировать, так что размер соединяемых двух наборов намного меньше.
Поскольку каждый BGP (шаблон основного графика), который представляет собой набор тройных шаблонов, выполняется как блок (по существу), движок может свободно изменять порядок в BGP для обеспечения оптимальной производительности. Например, рассмотрим следующий BGP:
?a :someProperty ?b .
?c :anotherProperty ?d .
?b a :Class .
Выполнено как запрос требует декартова произведение, так как результаты первого шаблона не пересекаются со вторым шаблоном, поэтому результаты первых двух шаблонов являются декартовым произведением их отдельных результатов. Этот результат будет содержать гораздо больше результатов, чем нам действительно нужно, поскольку третий шаблон ограничивает возможные результаты первого шаблона, но мы не применяем это ограничение до конца. Но если мы переупорядочиваем так:
?b a :Class .
?a :someProperty ?b .
?c :anotherProperty ?d .
Нам все равно понадобится декартовой продукт, чтобы получить окончательные результаты, так как 2-й и 3-й шаблоны все еще не пересекаются, но путем переупорядочения мы ограничиваем размер результатов 2-го паттерна, что означает, что размер нашего декартова продукта будет намного меньше.
Есть несколько различных других оптимизаций, которые мы делаем, но я не собираюсь публиковать их здесь, так как он начинает подробно расспрашивать о внутренних компонентах SPARQL. Если кто-то заинтересован в более подробной информации, просто оставьте комментарий или отправьте мне твит @RobVesse