2012-04-24 9 views
9

私がコードを書くつもりならば、これは純粋に私自身の知識のためです。.Max()を使用します。.Max()vs OrderByDescending()。First()

最初の考えでは、.Max()は、最大を見つけるためにnumbersを1回通過するだけで、2番目の方法はすべてのものを並べ替えて最初のものを見つけなければなりません。したがって、それはO(n)O(n lg n)です。しかし、その後、私はそれが最高のものしか必要としていないことを知っているかもしれないと思っていました。

質問: は、LINQおよび/またはそれが全体の列挙をソートする必要があるとダウン.MAX(と本質的に同じにコードを沸騰しないことを把握するのに十分賢いコンパイラですか)?見つけ出す定量可能な方法はありますか?

IEnumerable<int> numbers = Enumerable.Range(1, 1000); 

int max = numbers.Max(); 
int max2 = numbers.OrderByDescending(x => x).First(); 

答えて

4

LINQ to Objectsについて話している場合は、いいえ、最適化しません。

おそらく、別のLINQプロバイダが行うことができますが、それは実装の詳細です。列挙のために

、リフレクターが私を与える実装は以下のとおりです。

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) 
{ 
    return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false); 
} 

First()

public static TSource First<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull("source"); 
    } 
    IList<TSource> list = source as IList<TSource>; 
    if (list != null) 
    { 
     if (list.Count > 0) 
     { 
      return list[0]; 
     } 
    } 
    else 
    { 
     using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
     { 
      if (enumerator.MoveNext()) 
      { 
       return enumerator.Current; 
      } 
     } 
    } 
    throw Error.NoElements(); 
} 
4

.Max()あなたOrderByDescendingソリューションではありませんが、O(n)は - ソートに依存し、それはおそらく、O(nlog(n))があります。

私は明らかにコンパイラの中身を知っているわけではありませんが、あなたが求めているのは、並べ替えを実現して一つのアイテムだけを.maxと同じにする最適化です。

+0

良い点付近でコード! +1 –

8

ためにLINQおよび/またはそうでないことを把握するのに十分な賢いコンパイラです列挙型全体をソートする必要があり、コードを.Max()と本質的に同じにしますか?

見つけるための定量化方法はありますか?

ストップウォッチを持つ単純なベンチマーク:

var numbers = Enumerable.Range(1, 10000000); 
    var sw = Stopwatch.StartNew(); 
    int max = numbers.Max(); 
    Console.WriteLine(sw.ElapsedMilliseconds); 
    sw.Restart(); 
    int max2 = numbers.OrderByDescending(x => x).First(); 
    Console.WriteLine(sw.ElapsedMilliseconds); 

マックス():70msで

のOrderBy():あなたが数を増やす場合は2066ms

はまた、[並べ替えは、()でOutOfMemoryExceptionで失敗それを超えて、Max()はそれを超えています。