Skip to content

Instantly share code, notes, and snippets.

@aholmes
Last active February 29, 2016 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aholmes/cff5800d07b5aec573c7 to your computer and use it in GitHub Desktop.
Save aholmes/cff5800d07b5aec573c7 to your computer and use it in GitHub Desktop.
Comparison of FP and OOP approaches to benchmark a simple operation. https://www.reddit.com/r/javascript/comments/48alyu/functional_programming_for_javascript_people/d0inhqq
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication3
{
class Program
{
static int add(int x , int y)
{
return x + y;
}
static void Main(string[] args)
{
const int runs = 500;
const int executions = 100000000;
var sw = new Stopwatch();
var rand = new Random();
var runAvgs = new long[runs];
var i = 0;
var run = 0;
while (run < runs)
{
sw.Start();
while (i < executions)
{
add(rand.Next(), rand.Next());
i++;
}
sw.Stop();
runAvgs[run] = sw.ElapsedMilliseconds;
run++;
}
Console.WriteLine(string.Format("Avg time: {0}ms", runAvgs.Average()));
Console.Read();
}
}
}
.namespace ConsoleApplication3
{
.class private auto ansi beforefieldinit ConsoleApplication3.Program
extends [mscorlib]System.Object
{
// Methods
.method private hidebysig static
int32 'add' (
int32 x,
int32 y
) cil managed
{
// Method begins at RVA 0x2050
// Code size 9 (0x9)
.maxstack 2
.locals init (
[0] int32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
} // end of method Program::'add'
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2068
// Code size 152 (0x98)
.maxstack 3
.entrypoint
.locals init (
[0] class [System]System.Diagnostics.Stopwatch,
[1] class [mscorlib]System.Random,
[2] int64[],
[3] int32,
[4] int32,
[5] bool,
[6] bool
)
IL_0000: nop
IL_0001: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
IL_0006: stloc.0
IL_0007: newobj instance void [mscorlib]System.Random::.ctor()
IL_000c: stloc.1
IL_000d: ldc.i4 500
IL_0012: newarr [mscorlib]System.Int64
IL_0017: stloc.2
IL_0018: ldc.i4.0
IL_0019: stloc.3
IL_001a: ldc.i4.0
IL_001b: stloc.s 4
IL_001d: br.s IL_0067
// loop start (head: IL_0067)
IL_001f: nop
IL_0020: ldloc.0
IL_0021: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_0026: nop
IL_0027: br.s IL_0041
// loop start (head: IL_0041)
IL_0029: nop
IL_002a: ldloc.1
IL_002b: callvirt instance int32 [mscorlib]System.Random::Next()
IL_0030: ldloc.1
IL_0031: callvirt instance int32 [mscorlib]System.Random::Next()
IL_0036: call int32 ConsoleApplication3.Program::'add'(int32, int32)
IL_003b: pop
IL_003c: ldloc.3
IL_003d: ldc.i4.1
IL_003e: add
IL_003f: stloc.3
IL_0040: nop
IL_0041: ldloc.3
IL_0042: ldc.i4 100000000
IL_0047: clt
IL_0049: stloc.s 5
IL_004b: ldloc.s 5
IL_004d: brtrue.s IL_0029
// end loop
IL_004f: ldloc.0
IL_0050: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0055: nop
IL_0056: ldloc.2
IL_0057: ldloc.s 4
IL_0059: ldloc.0
IL_005a: callvirt instance int64 [System]System.Diagnostics.Stopwatch::get_ElapsedMilliseconds()
IL_005f: stelem.i8
IL_0060: ldloc.s 4
IL_0062: ldc.i4.1
IL_0063: add
IL_0064: stloc.s 4
IL_0066: nop
IL_0067: ldloc.s 4
IL_0069: ldc.i4 500
IL_006e: clt
IL_0070: stloc.s 6
IL_0072: ldloc.s 6
IL_0074: brtrue.s IL_001f
// end loop
IL_0076: ldstr "Avg time: {0}ms"
IL_007b: ldloc.2
IL_007c: call float64 [System.Core]System.Linq.Enumerable::Average(class [mscorlib]System.Collections.Generic.IEnumerable`1<int64>)
IL_0081: box [mscorlib]System.Double
IL_0086: call string [mscorlib]System.String::Format(string, object)
IL_008b: call void [mscorlib]System.Console::WriteLine(string)
IL_0090: nop
IL_0091: call int32 [mscorlib]System.Console::Read()
IL_0096: pop
IL_0097: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x210c
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Program::.ctor
} // end of class ConsoleApplication3.Program
}
open System
let add(x, y) =
x + y
[<EntryPoint>]
let main argv =
let runs = 500;
let executions = 100000000;
let sw = System.Diagnostics.Stopwatch();
let rand = System.Random();
let runAvgs = Array.create runs 0L;
let mutable i = 0;
let mutable run = 0;
while run < runs do
sw.Start();
while i < executions do
add (rand.Next(), rand.Next()) |> ignore
i <- i + 1
sw.Stop();
runAvgs.[run] <- sw.ElapsedMilliseconds
run <- run + 1
printf "Avg time: %dms\n\n" (runAvgs
|> Array.averageBy (fun e -> float e)
|> Convert.ToInt64)
Console.Read() |> ignore
0
.class private auto ansi '<Module>'
extends [mscorlib]System.Object
{
} // end of class <Module>
.class public auto ansi abstract sealed Program
extends [mscorlib]System.Object
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 07 00 00 00 00 00
)
// Nested Types
.class nested assembly auto ansi serializable beforefieldinit main@28
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, float64>
{
// Methods
.method assembly specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2210
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, float64>::.ctor()
IL_0006: ret
} // end of method main@28::.ctor
.method public strict virtual
instance float64 Invoke (
int64 e
) cil managed
{
// Method begins at RVA 0x2218
// Code size 4 (0x4)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.1
IL_0002: conv.r8
IL_0003: ret
} // end of method main@28::Invoke
} // end of class main@28
// Methods
.method public static
int32 'add' (
int32 x,
int32 y
) cil managed
{
// Method begins at RVA 0x2050
// Code size 5 (0x5)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: ret
} // end of method Program::'add'
.method public static
int32 main (
string[] argv
) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2058
// Code size 410 (0x19a)
.maxstack 5
.entrypoint
.locals init (
[0] int32 runs,
[1] int32 executions,
[2] class [System]System.Diagnostics.Stopwatch sw,
[3] class [mscorlib]System.Random rand,
[4] int64[] runAvgs,
[5] int32 i,
[6] int32 run,
[7] int32,
[8] int32,
[9] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, class [FSharp.Core]Microsoft.FSharp.Core.Unit>,
[10] int64,
[11] float64,
[12] int64[],
[13] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, float64>,
[14] int64[],
[15] class [mscorlib]System.Collections.Generic.IEnumerable`1<int64>,
[16] class [mscorlib]System.Collections.Generic.IEnumerator`1<int64>,
[17] float64,
[18] float64,
[19] int32,
[20] float64,
[21] int32,
[22] class [mscorlib]System.IDisposable,
[23] float64,
[24] int32,
[25] int32
)
IL_0000: nop
IL_0001: ldc.i4 500
IL_0006: stloc.0
IL_0007: ldc.i4 100000000
IL_000c: stloc.1
IL_000d: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
IL_0012: stloc.2
IL_0013: newobj instance void [mscorlib]System.Random::.ctor()
IL_0018: stloc.3
IL_0019: ldloc.0
IL_001a: ldc.i8 0
IL_0023: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Create<int64>(int32, !!0)
IL_0028: stloc.s runAvgs
IL_002a: ldc.i4.0
IL_002b: stloc.s i
IL_002d: ldc.i4.0
IL_002e: stloc.s run
// loop start (head: IL_0030)
IL_0030: ldloc.s run
IL_0032: ldloc.0
IL_0033: bge.s IL_007e
IL_0035: ldloc.2
IL_0036: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
// loop start (head: IL_003b)
IL_003b: ldloc.s i
IL_003d: ldloc.1
IL_003e: bge.s IL_0060
IL_0040: ldloc.3
IL_0041: callvirt instance int32 [mscorlib]System.Random::Next()
IL_0046: ldloc.3
IL_0047: callvirt instance int32 [mscorlib]System.Random::Next()
IL_004c: call int32 Program::'add'(int32, int32)
IL_0051: stloc.s 7
IL_0053: ldloc.s 7
IL_0055: stloc.s 8
IL_0057: ldloc.s i
IL_0059: ldc.i4.1
IL_005a: add
IL_005b: stloc.s i
IL_005d: nop
IL_005e: br.s IL_003b
// end loop
IL_0060: ldloc.2
IL_0061: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0066: ldloc.s runAvgs
IL_0068: ldloc.s run
IL_006a: ldloc.2
IL_006b: callvirt instance int64 [System]System.Diagnostics.Stopwatch::get_ElapsedMilliseconds()
IL_0070: stelem.any [mscorlib]System.Int64
IL_0075: ldloc.s run
IL_0077: ldc.i4.1
IL_0078: add
IL_0079: stloc.s run
IL_007b: nop
IL_007c: br.s IL_0030
// end loop
IL_007e: ldstr "Avg time: %dms\n\n"
IL_0083: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, int64>::.ctor(string)
IL_0088: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormat<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
IL_008d: stloc.s 9
IL_008f: ldloc.s runAvgs
IL_0091: stloc.s 12
IL_0093: newobj instance void Program/main@28::.ctor()
IL_0098: stloc.s 13
IL_009a: ldloc.s 12
IL_009c: stloc.s 14
IL_009e: ldloc.s 14
IL_00a0: box int64[]
IL_00a5: brfalse.s IL_00a9
IL_00a7: br.s IL_00bc
IL_00a9: ldstr "array"
IL_00ae: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
IL_00b3: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [mscorlib]System.Exception)
IL_00b8: pop
IL_00b9: nop
IL_00ba: br.s IL_00bd
IL_00bc: nop
IL_00bd: ldloc.s 14
IL_00bf: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1<int64>
IL_00c4: stloc.s 15
IL_00c6: ldloc.s 15
IL_00c8: box class [mscorlib]System.Collections.Generic.IEnumerable`1<int64>
IL_00cd: brfalse.s IL_00d1
IL_00cf: br.s IL_00e4
IL_00d1: ldstr "source"
IL_00d6: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
IL_00db: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [mscorlib]System.Exception)
IL_00e0: pop
IL_00e1: nop
IL_00e2: br.s IL_00e5
IL_00e4: nop
IL_00e5: ldloc.s 15
IL_00e7: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int64>::GetEnumerator()
IL_00ec: stloc.s 16
.try
{
IL_00ee: ldc.r8 0.0
IL_00f7: stloc.s 18
IL_00f9: ldc.i4.0
IL_00fa: stloc.s 19
// loop start (head: IL_00fc)
IL_00fc: ldloc.s 16
IL_00fe: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
IL_0103: brfalse.s IL_0121
IL_0105: ldloc.s 18
IL_0107: ldloc.s 13
IL_0109: ldloc.s 16
IL_010b: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int64>::get_Current()
IL_0110: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, float64>::Invoke(!0)
IL_0115: add
IL_0116: stloc.s 18
IL_0118: ldloc.s 19
IL_011a: ldc.i4.1
IL_011b: add
IL_011c: stloc.s 19
IL_011e: nop
IL_011f: br.s IL_00fc
// end loop
IL_0121: ldloc.s 19
IL_0123: brtrue.s IL_0127
IL_0125: br.s IL_0129
IL_0127: br.s IL_0141
IL_0129: call string [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/ErrorStrings::get_InputSequenceEmptyString()
IL_012e: ldstr "source"
IL_0133: newobj instance void [mscorlib]System.ArgumentException::.ctor(string, string)
IL_0138: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [mscorlib]System.Exception)
IL_013d: pop
IL_013e: nop
IL_013f: br.s IL_0142
IL_0141: nop
IL_0142: ldloc.s 18
IL_0144: stloc.s 20
IL_0146: ldloc.s 19
IL_0148: stloc.s 21
IL_014a: ldloc.s 20
IL_014c: ldloc.s 21
IL_014e: conv.r8
IL_014f: div
IL_0150: stloc.s 17
IL_0152: leave.s IL_0172
} // end .try
finally
{
IL_0154: ldloc.s 16
IL_0156: isinst [mscorlib]System.IDisposable
IL_015b: stloc.s 22
IL_015d: ldloc.s 22
IL_015f: brfalse.s IL_0163
IL_0161: br.s IL_0165
IL_0163: br.s IL_016f
IL_0165: ldloc.s 22
IL_0167: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_016c: ldnull
IL_016d: pop
IL_016e: endfinally
IL_016f: ldnull
IL_0170: pop
IL_0171: endfinally
} // end handler
IL_0172: ldloc.s 17
IL_0174: stloc.s 11
IL_0176: ldloc.s 11
IL_0178: stloc.s 23
IL_017a: ldloc.s 23
IL_017c: call int64 [mscorlib]System.Convert::ToInt64(float64)
IL_0181: stloc.s 10
IL_0183: ldloc.s 9
IL_0185: ldloc.s 10
IL_0187: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int64, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0)
IL_018c: pop
IL_018d: call int32 [mscorlib]System.Console::Read()
IL_0192: stloc.s 24
IL_0194: ldloc.s 24
IL_0196: stloc.s 25
IL_0198: ldc.i4.0
IL_0199: ret
} // end of method Program::main
} // end of class Program
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment