Skip to content

Instantly share code, notes, and snippets.

@axelheer
Last active August 29, 2015 14:19
Show Gist options
  • Save axelheer/3b701c91271b7c762586 to your computer and use it in GitHub Desktop.
Save axelheer/3b701c91271b7c762586 to your computer and use it in GitHub Desktop.
Basic benchmark for BigInteger
using System.Diagnostics;
namespace System.Numerics.Benchmark
{
public class Program
{
private static readonly Random s_random = new Random(1138);
private static int s_bits = 4096;
private static int s_vals = 100;
private static int s_runs = 10;
public static void Main(string[] args)
{
var op = "mul";
if (args.Length > 0)
op = args[0].ToLowerInvariant();
if (args.Length > 1)
s_bits = TryParse(args[1]);
if (args.Length > 2)
s_vals = TryParse(args[2]);
if (args.Length > 3)
s_runs = TryParse(args[3]);
Console.WriteLine("operation: {0}", op);
Console.WriteLine("# of bits: {0}", s_bits);
Console.WriteLine("# of vals: {0}", s_vals);
Console.WriteLine("# of runs: {0}", s_runs);
switch (op)
{
case "add":
Benchmark(s_bits, s_bits, 0,
(a, b, _) => BigInteger.Add(a, b));
break;
case "sub":
Benchmark(s_bits, s_bits, 0,
(a, b, _) => BigInteger.Subtract(a, b));
break;
case "mul":
Benchmark(s_bits, s_bits, 0,
(a, b, _) => BigInteger.Multiply(a, b));
break;
case "squ":
Benchmark(s_bits, 0, 0,
(a, _, __) => BigInteger.Multiply(a, a));
break;
case "div":
Benchmark(s_bits, s_bits / 2 + 1, 0,
(a, b, _) => BigInteger.Divide(a, b));
break;
case "mod":
Benchmark(s_bits, s_bits / 2 + 1, 0,
(a, b, _) => BigInteger.Remainder(a, b));
break;
case "gcd":
Benchmark(s_bits, s_bits, 0,
(a, b, _) => BigInteger.GreatestCommonDivisor(a, b));
break;
case "log":
Benchmark(s_bits, 0, 0,
(a, _, __) => BigInteger.Log(a));
break;
case "modpow":
Benchmark(s_bits, s_bits, s_bits,
(a, b, c) => BigInteger.ModPow(a, b, c));
break;
}
}
private static void Benchmark(
int leftSize, int rightSize, int otherSize,
Action<BigInteger, BigInteger, BigInteger> run)
{
var left = new BigInteger[s_vals];
var right = new BigInteger[s_vals];
var other = new BigInteger[s_vals];
// seed test values
for (var i = 0; i < s_vals; i++)
{
left[i] = RandomInteger(leftSize);
right[i] = RandomInteger(rightSize);
other[i] = RandomInteger(otherSize);
}
Console.WriteLine();
Console.Write("benchmark: ");
// run benchmarks
var result = long.MaxValue;
for (var j = 0; j < s_runs; j++)
{
var watch = new Stopwatch();
watch.Start();
for (var i = 0; i < s_vals; i++)
run(left[i], right[i], other[i]);
watch.Stop();
if (watch.ElapsedMilliseconds < result)
result = watch.ElapsedMilliseconds;
}
// tada!
Console.WriteLine("{0} ms / {1} ops", result, s_vals);
Console.WriteLine();
}
private static BigInteger RandomInteger(int bits)
{
if (bits <= 0)
return BigInteger.Zero;
var value = new byte[(bits + 7) / 8 + 1];
s_random.NextBytes(value);
value[value.Length - 1] = 0x00;
var result = new BigInteger(value);
return result.IsZero ? BigInteger.One : result;
}
private static int TryParse(string value)
{
var result = default(int);
if (int.TryParse(value, out result) && result > 0)
return result;
return 1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment