Как улучшить производительность выбора предметов в C # Linq (Большая коллекция) - PullRequest
0 голосов
/ 18 мая 2018
  1. У меня есть большая коллекция объектов (например, 100 000)
  2. Эти объекты не имеют индексов или какой-либо информации об их размере или расположении
  3. Если пользовательская высота не указанаЕсли для каждого объекта задана высота по умолчанию (например, 30)
  4. Для каждого элемента (в соответствии с индексом) можно определить собственную высоту
  5. Важно, чтобы объекты находились в IList collection

Предоставляя текущие значения Top и Height, я хотел бы получить объекты, расположенные в этой области.На основе позиции элементов в списке, высоты по умолчанию / пользовательской высоты и определения сцены.Я подготовил решение, но, к сожалению, оно неэффективно.Можете ли вы помочь мне улучшить производительность?

Моя неэффективная функция:

static List<int> GetIndexes(double y, double sceneHeight)
    {               
        int index1 = 0;     
        var dataIndexed = (from d in Data.Cast<object>() select new { Index = index1++});//IList casting Data.Cast<object>()                

        double top = 0;
        double height = 0;  
        int index2 = 0;

        var xr = (from di in dataIndexed
                  join definition in Definitions on di.Index equals definition.Index into X
                  from x in X.DefaultIfEmpty()                    
                  select new
                  {
                      Index = index2++,
                      Top = top += height,
                      Height = height = (x == null ? DefaultHeight : x.Height) //Default or Custom height

                  });                   
        return (from i in xr where i.Top >= y && i.Top < y + sceneHeight select i.Index).ToList();          
    }

Определение моего пользовательского объекта:

public class ItemDefinition
{
    public int Index { get; set; }
    public double Height { get; set; }
}

Тест:

public static void Main()
    {
        CreateData();
        CreateDefinitions();            
        double expectedTop = 30;        
        double expectedHeight = 201;
        DateTime start = DateTime.Now;
        List<int> indexes = GetIndexes(expectedTop, expectedHeight);
        Console.WriteLine("Duration: " + (DateTime.Now - start).TotalMilliseconds.ToString() + " ms");
        foreach(int index in indexes)
            Console.WriteLine(index);
    }

Демонстрация в реальном времени на .NET Fiddle

...