これらのメソッド呼び出しの最後の3つは、約 最初の4つの時間の2倍。
唯一の違いは、それらの引数が整数に収まらないことです。しかし、これは重要ですか?パラメータはlongとして宣言されているため、とにかく計算にはlongを使用する必要があります。モジュロ演算は、numbers> maxintに対して別のアルゴリズムを使用しますか?
私はamdathlon643200 +、winxp sp3、vs2008を使用しています。
Stopwatch sw = new Stopwatch();
TestLong(sw, int.MaxValue - 3l);
TestLong(sw, int.MaxValue - 2l);
TestLong(sw, int.MaxValue - 1l);
TestLong(sw, int.MaxValue);
TestLong(sw, int.MaxValue + 1l);
TestLong(sw, int.MaxValue + 2l);
TestLong(sw, int.MaxValue + 3l);
Console.ReadLine();
static void TestLong(Stopwatch sw, long num)
{
long n = 0;
sw.Reset();
sw.Start();
for (long i = 3; i < 20000000; i++)
{
n += num % i;
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
編集: 私は今Cで同じことを試しましたが、ここでは問題は発生しません。すべてのモジュロ演算は、最適化をオンにした場合とオンにしない場合のリリースとデバッグモードで同時にかかります。
#include "stdafx.h"
#include "time.h"
#include "limits.h"
static void TestLong(long long num)
{
long long n = 0;
clock_t t = clock();
for (long long i = 3; i < 20000000LL*100; i++)
{
n += num % i;
}
printf("%d - %lld\n", clock()-t, n);
}
int main()
{
printf("%i %i %i %i\n\n", sizeof (int), sizeof(long), sizeof(long long), sizeof(void*));
TestLong(3);
TestLong(10);
TestLong(131);
TestLong(INT_MAX - 1L);
TestLong(UINT_MAX +1LL);
TestLong(INT_MAX + 1LL);
TestLong(LLONG_MAX-1LL);
getchar();
return 0;
}
EDIT2:
素晴らしい提案をありがとう。.netとc(デバッグモードとリリースモードの両方)は、余りを計算するためにアトミックにcpu命令を使用しませんが、関数を呼び出します。
cプログラムでは、「_allrem」という名前を取得できました。また、このファイルの完全なソースコメントが表示されたため、このアルゴリズムは、.netアプリケーションの場合のように、被除数ではなく32ビット除数を特別に使用するという情報を見つけました。
また、cプログラムのパフォーマンスは、除数の値によってのみ影響を受け、被除数には影響されないこともわかりました。別のテストでは、.netプログラムの剰余関数のパフォーマンスは、被除数と除数の両方に依存することが示されました。
ところで:long long値の単純な加算でさえ、連続するaddおよびadc命令によって計算されます。したがって、私のプロセッサが自分自身を64ビットと呼んでも、実際にはそうではありません:(
EDIT3:
VisualStudio2010でコンパイルされたWindows7x64エディションでcアプリを実行しました。面白いことに、(アセンブリソースを確認した)真の64ビット命令が使用されていますが、パフォーマンスの動作は同じままです。