Может кто-нибудь, пожалуйста, продемонстрировать для меня более эффективный алгоритм работы с декартовым продуктом, чем тот, который я использую в настоящее время (при условии, что он есть). Я огляделся вокруг и немного искал, но не вижу ничего очевидного, поэтому я мог бы что-то упустить.Эффективный декартовы алгоритм продукта
foreach (int i in is) {
foreach (int j in js) {
//Pair i and j
}
}
Это очень упрощенная версия того, что я делаю в своем коде. Два целых числа - это ключи поиска, которые используются для извлечения одного или нескольких объектов, и все объекты из двух поисков соединяются вместе в новые объекты.
Этот небольшой блок кода в гораздо более сложной системе становится основным узким местом производительности, поскольку набор данных, который он использует, масштабируется. Некоторые из них, вероятно, могут быть смягчены путем улучшения структуры данных, используемых для хранения объектов и поисковых запросов, но основная проблема, которую я чувствую, по-прежнему является вычислением самого декартового произведения.
Редактировать
Так еще несколько фона на моем конкретном использовании алгоритма, чтобы увидеть, если может быть любые приемы, которые я могу использовать в ответ на комментарий Марка. Общая система - это механизм запросов SPARQL, который обрабатывает запросы SPARQL по наборам данных Graph, SPARQL - это язык, основанный на шаблонах, поэтому каждый запрос состоит из серии шаблонов, сопоставленных с графиком. В случае, когда два последующих шаблона не имеют общих переменных (они не пересекаются), необходимо вычислить декартово произведение решений, созданных двумя шаблонами, чтобы получить набор возможных решений для общего запроса. Может быть любое количество шаблонов, и мне, возможно, придется вычислять декартовы произведения несколько раз, что может привести к довольно экспоненциальному расширению возможных решений, если запрос состоит из серии непересекающихся шаблонов.
Как-то из существующих ответов я сомневаюсь, есть ли какие-либо приемы, которые можно применить
Update
Так я думал, что после обновления на то, что я реализовывал для того, чтобы свести к минимуму необходимость сделать декартово продуктов и, таким образом, оптимизировать механизм запросов в целом. Обратите внимание, что не всегда возможно полностью устранить необходимость в продуктах, но почти всегда можно оптимизировать, так что размер соединяемых двух наборов намного меньше.
Поскольку каждый шаблон BGP (Basic Graph Pattern), который представляет собой набор трехмерных шаблонов, выполняется как блок (по существу), движок может свободно изменять шаблоны в BGP для обеспечения оптимальной производительности. Например, рассмотрим следующий протокол BGP:
?a :someProperty ?b .
?c :anotherProperty ?d .
?b a :Class .
Executed как запрос требует декартово произведение, так как результаты первого шаблона не пересекаются со второго рисунка, так что результаты первых двух моделей является декартово произведение их индивидуальные результаты. Этот результат будет содержать гораздо больше результатов, чем нам действительно нужно, поскольку третий шаблон ограничивает возможные результаты первого шаблона, но мы не применяем это ограничение до конца. Но если мы реорганизовать так:
?b a :Class .
?a :someProperty ?b .
?c :anotherProperty ?d .
Мы все еще нуждаемся в декартово произведение, чтобы получить окончательные результаты, так как второй и 3-й модели еще не пересекаются, но переупорядочив мы ограничиваем размер результатов 2-го рисунка что означает, что размер нашего декартова продукта будет намного меньше.
Есть несколько различных других оптимизаций, которые мы делаем, но я не собираюсь публиковать их здесь, так как он начинает подробно расспрашивать о внутренних компонентах SPARQL. Если кто-то заинтересованы в дальнейших деталях просто оставить комментарий или отправить мне твит @RobVesse
http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx – tugberk