Подтвердить что ты не робот

Почему этот Cross Join настолько медленный в Linq?

Я написал эту часть Linq, чтобы обрабатывать CROSS Join так же, как и база данных между несколькими списками.

Но по какой-то причине он очень медленный, когда какой-либо из списков превышает 3000. Я бы подождал 30? Эти списки могут быть очень большими.

Этот запрос зацикливается для каждой связи с другими данными списка, исходящими из ColumnDataIndex.

Любой совет?

ОБНОВЛЕНИЕ ** - Данные вставляются в обычные списки, которые создаются перед использованием из настроенных источников. Это все в памяти на данный момент.

RunningResult[parameter.Uid] = (from source_row in RunningResult[parameter.Uid]
                            from target_row in ColumnDataIndex[dest_key]
                            where GetColumnFromUID(source_row, rel.SourceColumn) == GetColumnFromUID(target_row, rel.TargetColumn)
                            select new Row()
                            {
                                Columns = MergeColumns(source_row.Columns, target_row.Columns)

                            }).ToList();

Две дополнительные функции:

MergeColumns: принимает столбцы из двух элементов и объединяет их в один массив.

public static Columnn[] MergeColumns(Column[] source_columns, Column[] target_columns)
{
      Provider.Data.BucketColumn[] new_column = new Provider.Data.BucketColumn[source_columns.Length + target_columns.Length];
      source_columns.CopyTo(new_column, 0);
      target_columns.CopyTo(new_column, source_columns.Length);
      return new_column;
  }

GetColumnFromUID: возвращает значение столбца в элементе, соответствующем указанному столбцу uid.

private static String GetColumnFromUID(Row row, String column_uid)
  {
       if (row != null)
       {
           var dest_col = row.Columns.FirstOrDefault(col => col.ColumnUid == column_uid);
           return dest_col == null ? "" + row.RowId : dest_col.Value.ToString().ToLower();
       }
       else return String.Empty;

  }

Update:

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

4b9b3361

Ответ 1

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

LINQ имеет свою собственную операцию внутреннего соединения, Join, поэтому вам даже не нужно писать самостоятельно:

RunningResult[parameter.Uid] = (from source_row in RunningResult[parameter.Uid]
                                join target_row in ColumnDataIndex[dest_key]
                                on GetColumnFromUID(source_row, rel.SourceColumn) equals
                                    GetColumnFromUID(target_row, rel.TargetColumn)
                                select new Row()
                                {
                                    Columns = MergeColumns(source_row.Columns, target_row.Columns)

                                }).ToList();

Ответ 2

Вы не выполняете перекрестное соединение, а внутреннее соединение с предложением ON, только в вашем случае, предложение ON в предикате where.

Внутреннее соединение обычно выполняется с двумя хэш-наборами/таблицами, поэтому вы можете быстро найти строку в наборе X на основе значения в строке Y.

Итак, ответ "weston" в порядке, но вам нужно использовать словари/хеш-таблицы, чтобы сделать его очень быстрым. Имейте в виду, что может быть больше строк на ключ. Вы можете использовать многозначную хэш-таблицу/словарь, подобную этой: https://github.com/SolutionsDesign/Algorithmia/blob/master/SD.Tools.Algorithmia/GeneralDataStructures/MultiValueDictionary.cs