Skip to content

Instantly share code, notes, and snippets.

@aantron
Last active August 22, 2017 08:46
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 aantron/d6c5c86ba8142f8e2106a1ed96a4fb8d to your computer and use it in GitHub Desktop.
Save aantron/d6c5c86ba8142f8e2106a1ed96a4fb8d to your computer and use it in GitHub Desktop.
Code, data for OCaml ordinary and polymorphic variant performance comparison https://discuss.ocaml.org/t/lwt-core-refactored-and-documented-to-be-contributor-friendly/161/28
; Generated from
;
; type ordinary =
; | A | B | C | D
; | E of int | F of int | G of int | H of int
;
; let pattern_match = function
; | A -> 0
; | B -> 1
; | C -> 2
; | D -> 3
; | E i -> i
; | F i -> i + 1
; | G i -> i + 2
; | H i -> i + 3
;
; by
;
; ocamlopt -S -c ordinary.ml
_camlOrdinary__pattern_match_1208:
.cfi_startproc
; Test the low bit of the argument.
movq %rax, %rbx
testb $1, %bl
; If the low bit is zero, jump to L104.
je L104
; If here, the low bit is one, so %rbx contains an unboxed integer,
; i.e. a no-argument constructor, so A, B, C, or D.
; Shift the 63 high bits to be the 63 low bits, replacing the wonky
; OCaml integer by an ordinary integer. Then, use it to load one of
; the offsets from the jump table at L110 into %rdx.
sarq $1, %rbx
leaq L110(%rip), %rax
movslq (%rax,%rbx,4), %rdx
; Compute the location of the case and jump to it. Each case returns
; an unboxed OCaml integer; see the source code.
addq %rdx, %rax
jmp *%rax
.align 2
L110:
.long L108 - L110
.long L107 - L110
.long L106 - L110
.long L105 - L110
.text
.align 2
L108:
movq $1, %rax
ret
.align 2
L107:
movq $3, %rax
ret
.align 2
L106:
movq $5, %rax
ret
.align 2
L105:
movq $7, %rax
ret
.align 2
L104:
; If here, the low bit of %rbx is zero, so %rbx contains a pointer
; to a memory block that represents E, F, G, or H. The code is
; largely similar to the code for A, B, C, D above, except:
; Load the low byte (tag) of the memory block *at* %rbx into %rax.
movzbq -8(%rbx), %rax
; This time, we use that *tag* to index into the jump offset table,
; at L111.
leaq L111(%rip), %rdx
movslq (%rdx,%rax,4), %rax
addq %rax, %rdx
jmp *%rdx
.align 2
L111:
.long L103 - L111
.long L102 - L111
.long L101 - L111
.long L100 - L111
.text
.align 2
L103:
; Also, the code in the cases is a bit different, because we load a
; word from the block (movq), then optionally add an immediate
; integer to it.
movq (%rbx), %rax
ret
.align 2
L102:
movq (%rbx), %rax
addq $2, %rax
ret
.align 2
L101:
movq (%rbx), %rax
addq $4, %rax
ret
.align 2
L100:
movq (%rbx), %rax
addq $6, %rax
ret
.cfi_endproc
; Generated from
;
; let pattern_match = function
; | `Foo -> 1
; | `Bar -> 2
; | `Baz -> 3
; | `Qux -> 4
;
; by
;
; ocamlopt -S -c polymorphic.ml
; `Foo hashes to 3,505,894, represented in OCaml as 7,011,789.
; `Bar hashes to 3,303,859, represented in OCaml as 6,607,719.
; `Baz hashes to 3,303,867, represented in OCaml as 6,607,735.
; `Qux hashes to 4,054,260, represented in OCaml as 8,108,521.
_camlPolymorphic__pattern_match_1199:
.cfi_startproc
; `Foo is close to the middle of the range, so test for it first.
cmpq $7011789, %rax
; If less than `Foo, we have `Bar or `Baz. Go to that branch.
; jl is "jump if less."
jl L101
; Otherwise, it might be `Foo or `Qux. Check for `Qux.
cmpq $8108521, %rax
; If less than `Qux, it's definitely `Foo. Go to that branch.
; As an aside, the above comparison is not necessary. This branch
; could be replaced by a je instruction.
jl L102
; It was `Foo or more, but then `Qux or more, so return the OCaml
; representation of four.
movq $9, %rax
ret
.align 2
L102:
; This is the `Foo branch.
movq $3, %rax
ret
.align 2
L101:
; This is the `Bar or `Baz branch. Compare with `Baz.
cmpq $6607735, %rax
; If less than `Baz, it is `Bar. Go to that branch.
jl L100
; This is the `Baz branch.
movq $7, %rax
ret
.align 2
L100:
; This is the `Bar branch.
movq $5, %rax
ret
.cfi_endproc
(* ocamlfind opt -thread -linkpkg -package core_bench allocation.ml *)
(* Returns a different integer each time it's called. Used to suppress
potential optimizations. *)
let a_value =
let current = ref 0 in
fun () ->
current := !current + 1;
!current
let dummy =
Core_bench.Bench.Test.create ~name:"dummy" (fun () -> ())
(* Used to measure the overhead of testing. *)
let control =
Core_bench.Bench.Test.create ~name:"control" (fun () ->
a_value () |> ignore)
type ordinary_1 =
| A of int
| B of int
let ordinary_1 =
Core_bench.Bench.Test.create ~name:"ordinary-1" (fun () ->
A (a_value ()) |> ignore)
type polymorphic_1 =
[ `A of int
| `B of int]
let polymorphic_1 =
Core_bench.Bench.Test.create ~name:"polymorphic-1" (fun () ->
`A (a_value ()) |> ignore)
type ordinary_2 =
| A of int * int
| B of int * int
let ordinary_2 =
Core_bench.Bench.Test.create ~name:"ordinary-2" (fun () ->
let v = a_value () in
A (v, v) |> ignore)
type polymorphic_2 =
[ `A of int * int
| `B of int * int]
let polymorphic_2 =
Core_bench.Bench.Test.create ~name:"polymorphic-2" (fun () ->
let v = a_value () in
`A (v, v) |> ignore)
let allocation_tests =
let tests =
[control;
ordinary_1;
polymorphic_1;
ordinary_2;
polymorphic_2]
in
Core_bench.Bench.make_command (dummy::tests)
let () =
Core.Command.run allocation_tests
(* ocamlfind opt -thread -linkpkg -package core_bench matching.ml *)
(* This file is best read with all internal modules folded, as these contain a
large amount of repetitive code.
This benchmark tests pattern matching of ordinary and polymorphic variants
from 4 to 128 cases. *)
(* Given an array of values (from one of the VARIANT modules below), chooses
consecutive ones each time it is called. To make the overhead identical, all
arrays have 128 elements. For variants with less than 128 cases, elements are
repeated. *)
let choose : 'a. 'a array -> (unit -> 'a) = fun all ->
let index = ref 0 in
let max_index = Array.length all - 1 in
fun () ->
let result = all.(!index) in
begin if !index >= max_index then
index := 0
else
index := !index + 1
end;
result
module type VARIANT =
sig
type t
val arbitrary : unit -> t
val pattern_match : t -> int
val name : string
end
(* The control test is used to estimate the overhead of testing itself, such as
iterating over values in function [choose], calling closures from first-class
modules, etc. *)
module Control =
struct
type t = unit
let arbitrary = choose
[|(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ();
(); (); (); (); (); (); (); ()|]
let pattern_match () = 0
let name = "control"
end
let control = (module Control : VARIANT)
module Ordinary_4 =
struct
type t =
| A0 | A1 | A2 | A3
let arbitrary = choose
[| A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3;
A0; A1; A2; A3; A0; A1; A2; A3|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
let name = "ordinary-4"
end
let ordinary_4 = (module Ordinary_4 : VARIANT)
module Ordinary_8 =
struct
type t =
| A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
let arbitrary = choose
[| A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7;
A0; A1; A2; A3; A4; A5; A6; A7|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
| A4 -> 4
| A5 -> 5
| A6 -> 6
| A7 -> 7
let name = "ordinary-8"
end
let ordinary_8 = (module Ordinary_8 : VARIANT)
module Ordinary_16 =
struct
type t =
| A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
| A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15
let arbitrary = choose
[| A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
| A4 -> 4
| A5 -> 5
| A6 -> 6
| A7 -> 7
| A8 -> 8
| A9 -> 9
| A10 -> 10
| A11 -> 11
| A12 -> 12
| A13 -> 13
| A14 -> 14
| A15 -> 15
let name = "ordinary-16"
end
let ordinary_16 = (module Ordinary_16 : VARIANT)
module Ordinary_32 =
struct
type t =
| A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
| A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15
| A16 | A17 | A18 | A19 | A20 | A21 | A22 | A23
| A24 | A25 | A26 | A27 | A28 | A29 | A30 | A31
let arbitrary = choose
[| A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
| A4 -> 4
| A5 -> 5
| A6 -> 6
| A7 -> 7
| A8 -> 8
| A9 -> 9
| A10 -> 10
| A11 -> 11
| A12 -> 12
| A13 -> 13
| A14 -> 14
| A15 -> 15
| A16 -> 16
| A17 -> 17
| A18 -> 18
| A19 -> 19
| A20 -> 20
| A21 -> 21
| A22 -> 22
| A23 -> 23
| A24 -> 24
| A25 -> 25
| A26 -> 26
| A27 -> 27
| A28 -> 28
| A29 -> 29
| A30 -> 30
| A31 -> 31
let name = "ordinary-32"
end
let ordinary_32 = (module Ordinary_32 : VARIANT)
module Ordinary_64 =
struct
type t =
| A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
| A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15
| A16 | A17 | A18 | A19 | A20 | A21 | A22 | A23
| A24 | A25 | A26 | A27 | A28 | A29 | A30 | A31
| A32 | A33 | A34 | A35 | A36 | A37 | A38 | A39
| A40 | A41 | A42 | A43 | A44 | A45 | A46 | A47
| A48 | A49 | A50 | A51 | A52 | A53 | A54 | A55
| A56 | A57 | A58 | A59 | A60 | A61 | A62 | A63
let arbitrary = choose
[| A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A32; A33; A34; A35; A36; A37; A38; A39;
A40; A41; A42; A43; A44; A45; A46; A47;
A48; A49; A50; A51; A52; A53; A54; A55;
A56; A57; A58; A59; A60; A61; A62; A63;
A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A32; A33; A34; A35; A36; A37; A38; A39;
A40; A41; A42; A43; A44; A45; A46; A47;
A48; A49; A50; A51; A52; A53; A54; A55;
A56; A57; A58; A59; A60; A61; A62; A63|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
| A4 -> 4
| A5 -> 5
| A6 -> 6
| A7 -> 7
| A8 -> 8
| A9 -> 9
| A10 -> 10
| A11 -> 11
| A12 -> 12
| A13 -> 13
| A14 -> 14
| A15 -> 15
| A16 -> 16
| A17 -> 17
| A18 -> 18
| A19 -> 19
| A20 -> 20
| A21 -> 21
| A22 -> 22
| A23 -> 23
| A24 -> 24
| A25 -> 25
| A26 -> 26
| A27 -> 27
| A28 -> 28
| A29 -> 29
| A30 -> 30
| A31 -> 31
| A32 -> 32
| A33 -> 33
| A34 -> 34
| A35 -> 35
| A36 -> 36
| A37 -> 37
| A38 -> 38
| A39 -> 39
| A40 -> 40
| A41 -> 41
| A42 -> 42
| A43 -> 43
| A44 -> 44
| A45 -> 45
| A46 -> 46
| A47 -> 47
| A48 -> 48
| A49 -> 49
| A50 -> 50
| A51 -> 51
| A52 -> 52
| A53 -> 53
| A54 -> 54
| A55 -> 55
| A56 -> 56
| A57 -> 57
| A58 -> 58
| A59 -> 59
| A60 -> 60
| A61 -> 61
| A62 -> 62
| A63 -> 63
let name = "ordinary-64"
end
let ordinary_64 = (module Ordinary_64 : VARIANT)
module Ordinary_128 =
struct
type t =
| A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7
| A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15
| A16 | A17 | A18 | A19 | A20 | A21 | A22 | A23
| A24 | A25 | A26 | A27 | A28 | A29 | A30 | A31
| A32 | A33 | A34 | A35 | A36 | A37 | A38 | A39
| A40 | A41 | A42 | A43 | A44 | A45 | A46 | A47
| A48 | A49 | A50 | A51 | A52 | A53 | A54 | A55
| A56 | A57 | A58 | A59 | A60 | A61 | A62 | A63
| A64 | A65 | A66 | A67 | A68 | A69 | A70 | A71
| A72 | A73 | A74 | A75 | A76 | A77 | A78 | A79
| A80 | A81 | A82 | A83 | A84 | A85 | A86 | A87
| A88 | A89 | A90 | A91 | A92 | A93 | A94 | A95
| A96 | A97 | A98 | A99 | A100 | A101 | A102 | A103
| A104 | A105 | A106 | A107 | A108 | A109 | A110 | A111
| A112 | A113 | A114 | A115 | A116 | A117 | A118 | A119
| A120 | A121 | A122 | A123 | A124 | A125 | A126 | A127
let arbitrary = choose
[| A0; A1; A2; A3; A4; A5; A6; A7;
A8; A9; A10; A11; A12; A13; A14; A15;
A16; A17; A18; A19; A20; A21; A22; A23;
A24; A25; A26; A27; A28; A29; A30; A31;
A32; A33; A34; A35; A36; A37; A38; A39;
A40; A41; A42; A43; A44; A45; A46; A47;
A48; A49; A50; A51; A52; A53; A54; A55;
A56; A57; A58; A59; A60; A61; A62; A63;
A64; A65; A66; A67; A68; A69; A70; A71;
A72; A73; A74; A75; A76; A77; A78; A79;
A80; A81; A82; A83; A84; A85; A86; A87;
A88; A89; A90; A91; A92; A93; A94; A95;
A96; A97; A98; A99; A100; A101; A102; A103;
A104; A105; A106; A107; A108; A109; A110; A111;
A112; A113; A114; A115; A116; A117; A118; A119;
A120; A121; A122; A123; A124; A125; A126; A127|]
let pattern_match = function
| A0 -> 0
| A1 -> 1
| A2 -> 2
| A3 -> 3
| A4 -> 4
| A5 -> 5
| A6 -> 6
| A7 -> 7
| A8 -> 8
| A9 -> 9
| A10 -> 10
| A11 -> 11
| A12 -> 12
| A13 -> 13
| A14 -> 14
| A15 -> 15
| A16 -> 16
| A17 -> 17
| A18 -> 18
| A19 -> 19
| A20 -> 20
| A21 -> 21
| A22 -> 22
| A23 -> 23
| A24 -> 24
| A25 -> 25
| A26 -> 26
| A27 -> 27
| A28 -> 28
| A29 -> 29
| A30 -> 30
| A31 -> 31
| A32 -> 32
| A33 -> 33
| A34 -> 34
| A35 -> 35
| A36 -> 36
| A37 -> 37
| A38 -> 38
| A39 -> 39
| A40 -> 40
| A41 -> 41
| A42 -> 42
| A43 -> 43
| A44 -> 44
| A45 -> 45
| A46 -> 46
| A47 -> 47
| A48 -> 48
| A49 -> 49
| A50 -> 50
| A51 -> 51
| A52 -> 52
| A53 -> 53
| A54 -> 54
| A55 -> 55
| A56 -> 56
| A57 -> 57
| A58 -> 58
| A59 -> 59
| A60 -> 60
| A61 -> 61
| A62 -> 62
| A63 -> 63
| A64 -> 64
| A65 -> 65
| A66 -> 66
| A67 -> 67
| A68 -> 68
| A69 -> 69
| A70 -> 70
| A71 -> 71
| A72 -> 72
| A73 -> 73
| A74 -> 74
| A75 -> 75
| A76 -> 76
| A77 -> 77
| A78 -> 78
| A79 -> 79
| A80 -> 80
| A81 -> 81
| A82 -> 82
| A83 -> 83
| A84 -> 84
| A85 -> 85
| A86 -> 86
| A87 -> 87
| A88 -> 88
| A89 -> 89
| A90 -> 90
| A91 -> 91
| A92 -> 92
| A93 -> 93
| A94 -> 94
| A95 -> 95
| A96 -> 96
| A97 -> 97
| A98 -> 98
| A99 -> 99
| A100 -> 100
| A101 -> 101
| A102 -> 102
| A103 -> 103
| A104 -> 104
| A105 -> 105
| A106 -> 106
| A107 -> 107
| A108 -> 108
| A109 -> 109
| A110 -> 110
| A111 -> 111
| A112 -> 112
| A113 -> 113
| A114 -> 114
| A115 -> 115
| A116 -> 116
| A117 -> 117
| A118 -> 118
| A119 -> 119
| A120 -> 120
| A121 -> 121
| A122 -> 122
| A123 -> 123
| A124 -> 124
| A125 -> 125
| A126 -> 126
| A127 -> 127
let name = "ordinary-128"
end
let ordinary_128 = (module Ordinary_128 : VARIANT)
module Polymorphic_4 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3;
`A0; `A1; `A2; `A3; `A0; `A1; `A2; `A3|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
let name = "polymorphic-4"
end
let polymorphic_4 = (module Polymorphic_4 : VARIANT)
module Polymorphic_8 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 | `A4 | `A5 | `A6 | `A7 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
| `A4 -> 4
| `A5 -> 5
| `A6 -> 6
| `A7 -> 7
let name = "polymorphic-8"
end
let polymorphic_8 = (module Polymorphic_8 : VARIANT)
module Polymorphic_16 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 | `A4 | `A5 | `A6 | `A7
| `A8 | `A9 | `A10 | `A11 | `A12 | `A13 | `A14 | `A15 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
| `A4 -> 4
| `A5 -> 5
| `A6 -> 6
| `A7 -> 7
| `A8 -> 8
| `A9 -> 9
| `A10 -> 10
| `A11 -> 11
| `A12 -> 12
| `A13 -> 13
| `A14 -> 14
| `A15 -> 15
let name = "polymorphic-16"
end
let polymorphic_16 = (module Polymorphic_16 : VARIANT)
module Polymorphic_32 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 | `A4 | `A5 | `A6 | `A7
| `A8 | `A9 | `A10 | `A11 | `A12 | `A13 | `A14 | `A15
| `A16 | `A17 | `A18 | `A19 | `A20 | `A21 | `A22 | `A23
| `A24 | `A25 | `A26 | `A27 | `A28 | `A29 | `A30 | `A31 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
| `A4 -> 4
| `A5 -> 5
| `A6 -> 6
| `A7 -> 7
| `A8 -> 8
| `A9 -> 9
| `A10 -> 10
| `A11 -> 11
| `A12 -> 12
| `A13 -> 13
| `A14 -> 14
| `A15 -> 15
| `A16 -> 16
| `A17 -> 17
| `A18 -> 18
| `A19 -> 19
| `A20 -> 20
| `A21 -> 21
| `A22 -> 22
| `A23 -> 23
| `A24 -> 24
| `A25 -> 25
| `A26 -> 26
| `A27 -> 27
| `A28 -> 28
| `A29 -> 29
| `A30 -> 30
| `A31 -> 31
let name = "polymorphic-32"
end
let polymorphic_32 = (module Polymorphic_32 : VARIANT)
module Polymorphic_64 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 | `A4 | `A5 | `A6 | `A7
| `A8 | `A9 | `A10 | `A11 | `A12 | `A13 | `A14 | `A15
| `A16 | `A17 | `A18 | `A19 | `A20 | `A21 | `A22 | `A23
| `A24 | `A25 | `A26 | `A27 | `A28 | `A29 | `A30 | `A31
| `A32 | `A33 | `A34 | `A35 | `A36 | `A37 | `A38 | `A39
| `A40 | `A41 | `A42 | `A43 | `A44 | `A45 | `A46 | `A47
| `A48 | `A49 | `A50 | `A51 | `A52 | `A53 | `A54 | `A55
| `A56 | `A57 | `A58 | `A59 | `A60 | `A61 | `A62 | `A63 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A32; `A33; `A34; `A35; `A36; `A37; `A38; `A39;
`A40; `A41; `A42; `A43; `A44; `A45; `A46; `A47;
`A48; `A49; `A50; `A51; `A52; `A53; `A54; `A55;
`A56; `A57; `A58; `A59; `A60; `A61; `A62; `A63;
`A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A32; `A33; `A34; `A35; `A36; `A37; `A38; `A39;
`A40; `A41; `A42; `A43; `A44; `A45; `A46; `A47;
`A48; `A49; `A50; `A51; `A52; `A53; `A54; `A55;
`A56; `A57; `A58; `A59; `A60; `A61; `A62; `A63|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
| `A4 -> 4
| `A5 -> 5
| `A6 -> 6
| `A7 -> 7
| `A8 -> 8
| `A9 -> 9
| `A10 -> 10
| `A11 -> 11
| `A12 -> 12
| `A13 -> 13
| `A14 -> 14
| `A15 -> 15
| `A16 -> 16
| `A17 -> 17
| `A18 -> 18
| `A19 -> 19
| `A20 -> 20
| `A21 -> 21
| `A22 -> 22
| `A23 -> 23
| `A24 -> 24
| `A25 -> 25
| `A26 -> 26
| `A27 -> 27
| `A28 -> 28
| `A29 -> 29
| `A30 -> 30
| `A31 -> 31
| `A32 -> 32
| `A33 -> 33
| `A34 -> 34
| `A35 -> 35
| `A36 -> 36
| `A37 -> 37
| `A38 -> 38
| `A39 -> 39
| `A40 -> 40
| `A41 -> 41
| `A42 -> 42
| `A43 -> 43
| `A44 -> 44
| `A45 -> 45
| `A46 -> 46
| `A47 -> 47
| `A48 -> 48
| `A49 -> 49
| `A50 -> 50
| `A51 -> 51
| `A52 -> 52
| `A53 -> 53
| `A54 -> 54
| `A55 -> 55
| `A56 -> 56
| `A57 -> 57
| `A58 -> 58
| `A59 -> 59
| `A60 -> 60
| `A61 -> 61
| `A62 -> 62
| `A63 -> 63
let name = "polymorphic-64"
end
let polymorphic_64 = (module Polymorphic_64 : VARIANT)
module Polymorphic_128 =
struct
type t =
[ `A0 | `A1 | `A2 | `A3 | `A4 | `A5 | `A6 | `A7
| `A8 | `A9 | `A10 | `A11 | `A12 | `A13 | `A14 | `A15
| `A16 | `A17 | `A18 | `A19 | `A20 | `A21 | `A22 | `A23
| `A24 | `A25 | `A26 | `A27 | `A28 | `A29 | `A30 | `A31
| `A32 | `A33 | `A34 | `A35 | `A36 | `A37 | `A38 | `A39
| `A40 | `A41 | `A42 | `A43 | `A44 | `A45 | `A46 | `A47
| `A48 | `A49 | `A50 | `A51 | `A52 | `A53 | `A54 | `A55
| `A56 | `A57 | `A58 | `A59 | `A60 | `A61 | `A62 | `A63
| `A64 | `A65 | `A66 | `A67 | `A68 | `A69 | `A70 | `A71
| `A72 | `A73 | `A74 | `A75 | `A76 | `A77 | `A78 | `A79
| `A80 | `A81 | `A82 | `A83 | `A84 | `A85 | `A86 | `A87
| `A88 | `A89 | `A90 | `A91 | `A92 | `A93 | `A94 | `A95
| `A96 | `A97 | `A98 | `A99 | `A100 | `A101 | `A102 | `A103
| `A104 | `A105 | `A106 | `A107 | `A108 | `A109 | `A110 | `A111
| `A112 | `A113 | `A114 | `A115 | `A116 | `A117 | `A118 | `A119
| `A120 | `A121 | `A122 | `A123 | `A124 | `A125 | `A126 | `A127 ]
let arbitrary = choose
[| `A0; `A1; `A2; `A3; `A4; `A5; `A6; `A7;
`A8; `A9; `A10; `A11; `A12; `A13; `A14; `A15;
`A16; `A17; `A18; `A19; `A20; `A21; `A22; `A23;
`A24; `A25; `A26; `A27; `A28; `A29; `A30; `A31;
`A32; `A33; `A34; `A35; `A36; `A37; `A38; `A39;
`A40; `A41; `A42; `A43; `A44; `A45; `A46; `A47;
`A48; `A49; `A50; `A51; `A52; `A53; `A54; `A55;
`A56; `A57; `A58; `A59; `A60; `A61; `A62; `A63;
`A64; `A65; `A66; `A67; `A68; `A69; `A70; `A71;
`A72; `A73; `A74; `A75; `A76; `A77; `A78; `A79;
`A80; `A81; `A82; `A83; `A84; `A85; `A86; `A87;
`A88; `A89; `A90; `A91; `A92; `A93; `A94; `A95;
`A96; `A97; `A98; `A99; `A100; `A101; `A102; `A103;
`A104; `A105; `A106; `A107; `A108; `A109; `A110; `A111;
`A112; `A113; `A114; `A115; `A116; `A117; `A118; `A119;
`A120; `A121; `A122; `A123; `A124; `A125; `A126; `A127|]
let pattern_match = function
| `A0 -> 0
| `A1 -> 1
| `A2 -> 2
| `A3 -> 3
| `A4 -> 4
| `A5 -> 5
| `A6 -> 6
| `A7 -> 7
| `A8 -> 8
| `A9 -> 9
| `A10 -> 10
| `A11 -> 11
| `A12 -> 12
| `A13 -> 13
| `A14 -> 14
| `A15 -> 15
| `A16 -> 16
| `A17 -> 17
| `A18 -> 18
| `A19 -> 19
| `A20 -> 20
| `A21 -> 21
| `A22 -> 22
| `A23 -> 23
| `A24 -> 24
| `A25 -> 25
| `A26 -> 26
| `A27 -> 27
| `A28 -> 28
| `A29 -> 29
| `A30 -> 30
| `A31 -> 31
| `A32 -> 32
| `A33 -> 33
| `A34 -> 34
| `A35 -> 35
| `A36 -> 36
| `A37 -> 37
| `A38 -> 38
| `A39 -> 39
| `A40 -> 40
| `A41 -> 41
| `A42 -> 42
| `A43 -> 43
| `A44 -> 44
| `A45 -> 45
| `A46 -> 46
| `A47 -> 47
| `A48 -> 48
| `A49 -> 49
| `A50 -> 50
| `A51 -> 51
| `A52 -> 52
| `A53 -> 53
| `A54 -> 54
| `A55 -> 55
| `A56 -> 56
| `A57 -> 57
| `A58 -> 58
| `A59 -> 59
| `A60 -> 60
| `A61 -> 61
| `A62 -> 62
| `A63 -> 63
| `A64 -> 64
| `A65 -> 65
| `A66 -> 66
| `A67 -> 67
| `A68 -> 68
| `A69 -> 69
| `A70 -> 70
| `A71 -> 71
| `A72 -> 72
| `A73 -> 73
| `A74 -> 74
| `A75 -> 75
| `A76 -> 76
| `A77 -> 77
| `A78 -> 78
| `A79 -> 79
| `A80 -> 80
| `A81 -> 81
| `A82 -> 82
| `A83 -> 83
| `A84 -> 84
| `A85 -> 85
| `A86 -> 86
| `A87 -> 87
| `A88 -> 88
| `A89 -> 89
| `A90 -> 90
| `A91 -> 91
| `A92 -> 92
| `A93 -> 93
| `A94 -> 94
| `A95 -> 95
| `A96 -> 96
| `A97 -> 97
| `A98 -> 98
| `A99 -> 99
| `A100 -> 100
| `A101 -> 101
| `A102 -> 102
| `A103 -> 103
| `A104 -> 104
| `A105 -> 105
| `A106 -> 106
| `A107 -> 107
| `A108 -> 108
| `A109 -> 109
| `A110 -> 110
| `A111 -> 111
| `A112 -> 112
| `A113 -> 113
| `A114 -> 114
| `A115 -> 115
| `A116 -> 116
| `A117 -> 117
| `A118 -> 118
| `A119 -> 119
| `A120 -> 120
| `A121 -> 121
| `A122 -> 122
| `A123 -> 123
| `A124 -> 124
| `A125 -> 125
| `A126 -> 126
| `A127 -> 127
let name = "polymorphic-128"
end
let polymorphic_128 = (module Polymorphic_128 : VARIANT)
let pattern_matching : (module VARIANT) -> Core_bench.Bench.Test.t =
fun (module Variant) ->
Core_bench.Bench.Test.create
~name:Variant.name
(fun () -> ignore (Variant.pattern_match (Variant.arbitrary ())))
let dummy =
Core_bench.Bench.Test.create ~name:"dummy" (fun () -> ())
let pattern_matching_tests =
[control;
ordinary_4;
ordinary_8;
ordinary_16;
ordinary_32;
ordinary_64;
ordinary_128;
polymorphic_4;
polymorphic_8;
polymorphic_16;
polymorphic_32;
polymorphic_64;
polymorphic_128]
|> List.map pattern_matching
|> fun tests -> Core_bench.Bench.make_command (dummy::tests)
let () =
Core.Command.run pattern_matching_tests
4 6.98 17.91 7.63
8 6.98 21.57 7.92
16 6.98 21.23 8.38
32 6.98 21.50 8.62
64 6.98 21.46 9.07
128 6.98 21.33 9.54
Copy link

ghost commented Aug 22, 2017

What CPU was this ran on?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment