2020年09月20日
川俣晶の縁側ソフトウェアC# コーディング How To total 442 count

【入門級】平均値を計算するAverageメソッドは必ずしも速くない

Written By: 川俣 晶連絡先

Averageメソッドの死角 §

 Averageメソッドは返す型で値を積算していきます。そのためオバーフローが起こりにくいという特徴がある代わりに処理は遅めになります。

 逆に、整数型の値なら整数のまま積算して、個数で割るときに実数計算にすると、オーバーフローは起こりやすいのですが、計算はやや速くなります。

 実際に走らせて結果を見てみましょう。

罠の数々 §

  • 大量のデータを積算する処理はオーバーフローが起こりやすい。注意しよう。
  • 逆に、二桁の整数を十個ぐらいint型で積算してもオーバーフローは起こらない。オーバーフローを意識してデータ型を拡張する意味は無い。(最大でも99*10=990でしかない)

参考リンク §

Enumerable.Average メソッド

 より表現豊かな型で処理してくれるバリエーションであればあるほど処理時間も長くなることに注意しよう。上記のリンクからどんな型で処理されているのかを確認しておこう。

リポジトリ §

https://github.com/autumn009/cshowto

Average2 §

using System;

using System.Linq;

class Program

{

    private static double calc1(int[] ar)

    {

        var start = DateTimeOffset.Now;

        double sum = 0;

        for (int i = 0; i < 10000; i++) sum += ar.Average();

        Console.WriteLine(DateTimeOffset.Now - start);

        return sum;

    }

    private static double calc2(int[] ar)

    {

        var start = DateTimeOffset.Now;

        double sum = 0;

        for (int i = 0; i < 10000; i++)

        {

            int s = 0;

            foreach (var item in ar) s += item;

            sum += ((double)s / (double)ar.Length);

        }

        Console.WriteLine(DateTimeOffset.Now - start);

        return sum;

    }

    static void Main()

    {

        int[] ar = Enumerable.Range(0, 100000).ToArray();

        calc1(ar);

        calc2(ar);

    }

}

実行結果

00:00:05.8312844

00:00:02.3455346

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?