簡體   English   中英

計算數組中不同元素數量的最快方法

[英]Fastest way to count number of distinct elements in array

我有一類這樣的對象:

public class Individual
{
    public double[] Number { get; set; } = new double[2]{ 0.0, 0.0 };
}

我將這些類存儲在字典列表中,並提供Individual.Number的值:

selection = List<Dictionary<int, Individual>>

現在,我必須計算(整個列表中) Individual.Number的不同值的數量。 到目前為止,我所做的是:

selection.Values.SelectMany(list => list.Number).Distinct().Count();

我想知道這是最快的方法嗎? 如何提高性能?

謝謝,

在內部, Distinct()方法創建一個新的Set<T>而不指定大小。

如果您對元素數量有一個模糊的想法,這可以防止許多分配(和內存移動)。

而且,由於只需要Count(),因此可以直接將其包括在內(Credits @TimSchmelter)。

    public static int OptimizedDistinctAndCount<TSource>(this IEnumerable<TSource> source, int numberOfElements) {
        if (source == null) throw Error.ArgumentNull("source");
        var set = new HashSet<TSource>(numberOfElements);
        foreach (TSource element in source) {
           set.Add(element);
        }
        return set.Count;
    }

然后,您可以使用:

selection.Values.SelectMany(list => list.Number).OptimizedDistinctAndCount(123);

你怎么看待這件事?

public class Individual
{
  public double[] Numbers { get; set; }
  public Individual()
  {
    Numbers = new double[0];
  }
  public Individual(double[] values)
  {
    Numbers = values/*.ToArray() if a copy must be done*/;
  }
}

class Program
{
  static void Main()
  {
    // Populate data
    var selection = new List<Dictionary<int, Individual>>();
    var dico1 = new Dictionary<int, Individual>();
    var dico2 = new Dictionary<int, Individual>();
    selection.Add(dico1);
    selection.Add(dico2);
    dico1.Add(1, new Individual(new double[] { 1.2, 1.3, 4.0, 10, 40 }));
    dico1.Add(2, new Individual(new double[] { 1.2, 1.5, 4.0, 20, 40 }));
    dico2.Add(3, new Individual(new double[] { 1.7, 1.6, 5.0, 30, 60 }));
    // Count distinct
    var found = new List<double>();
    foreach ( var dico in selection )
      foreach ( var item in dico )
        foreach ( var value in item.Value.Numbers )
          if ( !found.Contains(value) )
            found.Add(value);
    // Must show 12
    Console.WriteLine("Distinct values of the data pool = " + found.Count);
    Console.ReadKey();
  }
}

這種方法消除了一些調用方法的時間。

進一步的優化將使用for循環而不是foreach,並可能使用鏈表而不是List(速度更快,但需要更多的內存)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM