From ccd5fa10988d610c8b3aad79a554f4f1606a51c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Wa=C5=9Bko?= Date: Mon, 26 Sep 2022 13:02:22 +0200 Subject: [PATCH] Add benchmarks for `==` and work days (#3735) There are a few operations whose timing we'd like to measure. --- test/Benchmarks/src/Equality.enso | 83 +++++++++++++++++++ test/Benchmarks/src/Time/Work_Days.enso | 27 ++++++ test/Benchmarks/src/Vector/Distinct.enso | 33 ++++++++ .../{Vector_Sort.enso => Vector/Sort.enso} | 2 +- test/Benchmarks/src/{ => Vector}/Vector.enso | 0 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 test/Benchmarks/src/Equality.enso create mode 100644 test/Benchmarks/src/Time/Work_Days.enso create mode 100644 test/Benchmarks/src/Vector/Distinct.enso rename test/Benchmarks/src/{Vector_Sort.enso => Vector/Sort.enso} (98%) rename test/Benchmarks/src/{ => Vector}/Vector.enso (100%) diff --git a/test/Benchmarks/src/Equality.enso b/test/Benchmarks/src/Equality.enso new file mode 100644 index 00000000000..d7a9415dbaf --- /dev/null +++ b/test/Benchmarks/src/Equality.enso @@ -0,0 +1,83 @@ +from Standard.Base import all +import Standard.Base.Data.Time.Duration + +import Standard.Test.Bench + +polyglot java import java.util.Random +polyglot java import org.graalvm.collections.Pair as Graal_Pair + +type Uniform_Type + Only_Ctor x y + +type Simple_Sum_Type + Variant_A + Variant_B + +type Sum_Type_With_Values + Ctor_A x y + Ctor_B x + +## Counts entries in the vector equal to a given element and checks if it is as + expected. +count_entries vector element expected_count=1 = + go ix acc = if ix >= vector.length then acc else + new_acc = if vector.at ix == element then acc+1 else acc + @Tail_Call go (ix+1) new_acc + count = go 0 0 + if count != expected_count then + msg = "Expected " + expected_count.to_text + " entries of " + element.to_text + ", but got " + count.to_text + IO.println msg + Panic.throw (Illegal_State_Error msg) + +## Alternative implementation delegating to equals, for comparing polyglot performance. +count_entries_polyglot vector element expected_count=1 = + go ix acc = if ix >= vector.length then acc else + new_acc = if (vector.at ix).equals element then acc+1 else acc + @Tail_Call go (ix+1) new_acc + count = go 0 0 + if count != expected_count then + msg = "Expected " + expected_count.to_text + " entries of " + element.to_text + ", but got " + count.to_text + IO.println msg + Panic.throw (Illegal_State_Error msg) + +main = + n = 100000 + iter_size = 100 + num_iterations = 10 + + integer_vec = Vector.new n (ix -> ix) + boolean_vec = integer_vec.map x-> + x % 5 == 0 + text_vec = integer_vec.map .to_text + + uniform_atom_vec = integer_vec.map x-> + Only_Ctor (x + 10) (x * 2) + simple_variant_atom_vec = integer_vec.map x-> + if x % 5 == 0 then Variant_A else Variant_B + complex_variant_atom_vec = integer_vec.map x-> + if x % 5 == 0 then Ctor_A (x + 10) (x * 2) else Ctor_B x + + polyglot_vec = integer_vec.map x-> + Graal_Pair.create (x + 10) (x * 2) + + first_day = Date.new 1971 + date_vec = integer_vec.map x-> + first_day + x.days + first_dt = Date_Time.new 1971 + datetime_vec = integer_vec.map x-> + first_dt + x.minutes + + Bench.measure (count_entries integer_vec 4567) "Integer Equality" iter_size num_iterations + Bench.measure (count_entries boolean_vec True expected_count=(n . div 5)) "Boolean Equality" iter_size num_iterations + Bench.measure (count_entries text_vec "4567") "Text Equality" iter_size num_iterations + Bench.measure (count_entries date_vec (Date.new 1980 12 30)) "Date Equality" iter_size num_iterations + Bench.measure (count_entries datetime_vec (Date_Time.new 1971 1 2 12 30)) "Date_Time Equality" iter_size num_iterations + + Bench.measure (count_entries uniform_atom_vec (Only_Ctor 110 200)) "Custom Atom Equality - single constructor" iter_size num_iterations + Bench.measure (count_entries simple_variant_atom_vec Variant_A expected_count=(n . div 5)) "Custom Atom Equality - 2 constructors without data" iter_size num_iterations + Bench.measure (count_entries complex_variant_atom_vec (Ctor_B 123)) "Custom Atom Equality - 2 constructors with data" iter_size num_iterations + + Bench.measure (count_entries polyglot_vec (Graal_Pair.create 110 200)) "Java Polyglot ==" iter_size num_iterations + Bench.measure (count_entries_polyglot polyglot_vec (Graal_Pair.create 110 200)) "Java Polyglot .equals" iter_size num_iterations + + Nothing diff --git a/test/Benchmarks/src/Time/Work_Days.enso b/test/Benchmarks/src/Time/Work_Days.enso new file mode 100644 index 00000000000..cd33cb6291d --- /dev/null +++ b/test/Benchmarks/src/Time/Work_Days.enso @@ -0,0 +1,27 @@ +from Standard.Base import all +from Standard.Base.Data.Index_Sub_Range import Sample +import Standard.Base.Data.Time.Duration + +import Standard.Test.Bench + +polyglot java import java.util.Random + +main = + iter_size = 50 + num_iterations = 10 + + first_day = Date.new 2020 1 1 + dates = Vector.new 1000 (x -> first_day + x.days) + holidays = dates.take (Sample 100 100) + shifts = [1, 5, 20, 100] + + shifts.each shift-> + shifted_dates = dates.map (d -> d + shift.days) + Bench.measure (dates.zip shifted_dates d1-> d2-> d1.work_days_until d2) "(Shift="+shift.to_text+") work_days_until" iter_size num_iterations + Bench.measure (dates.zip shifted_dates d1-> d2-> d1.work_days_until d2 holidays=holidays) "(Shift="+shift.to_text+") work_days_until with holidays" iter_size num_iterations + + Bench.measure (dates.map date-> date + shift.days) "(Shift="+shift.to_text+") add regular days" iter_size num_iterations + Bench.measure (dates.map date-> date.add_work_days shift) "(Shift="+shift.to_text+") add work days" iter_size num_iterations + Bench.measure (dates.map date-> date.add_work_days shift holidays=holidays) "(Shift="+shift.to_text+") add work days with holidays" iter_size num_iterations + + Nothing diff --git a/test/Benchmarks/src/Vector/Distinct.enso b/test/Benchmarks/src/Vector/Distinct.enso new file mode 100644 index 00000000000..4f555209dcd --- /dev/null +++ b/test/Benchmarks/src/Vector/Distinct.enso @@ -0,0 +1,33 @@ +from Standard.Base import all +import Standard.Base + +import Standard.Test.Bench + +polyglot java import java.util.Random +polyglot java import org.enso.base.Time_Utils + + +## Bench Utilities ============================================================ + +iter_size = 100 +num_iterations = 10 + +make_random_vec : Integer -> Base.Vector.Vector +make_random_vec n = + random_gen = Random.new n + Base.Vector.new n _->random_gen.nextLong + +# The Benchmarks ============================================================== + +main = + random_vec = make_random_vec 10000 + uniform_vec = Base.Vector.fill 10000 1 + + random_text_vec = random_vec.map .to_text + uniform_text_vec = random_vec.map .to_text + + Bench.measure (random_vec.distinct) "Random Integer Vector Distinct" iter_size num_iterations + Bench.measure (uniform_vec.distinct) "Uniform Integer Vector Distinct" iter_size num_iterations + + Bench.measure (random_text_vec.distinct) "Random Text Vector Distinct" iter_size num_iterations + Bench.measure (uniform_text_vec.distinct) "Uniform Text Vector Distinct" iter_size num_iterations diff --git a/test/Benchmarks/src/Vector_Sort.enso b/test/Benchmarks/src/Vector/Sort.enso similarity index 98% rename from test/Benchmarks/src/Vector_Sort.enso rename to test/Benchmarks/src/Vector/Sort.enso index daa7c55a516..044e049a794 100644 --- a/test/Benchmarks/src/Vector_Sort.enso +++ b/test/Benchmarks/src/Vector/Sort.enso @@ -2,7 +2,7 @@ from Standard.Base import all import Standard.Test.Bench -import project.Vector as Vector_Utils +import project.Vector.Vector as Vector_Utils polyglot java import java.util.Random polyglot java import org.enso.base.Time_Utils diff --git a/test/Benchmarks/src/Vector.enso b/test/Benchmarks/src/Vector/Vector.enso similarity index 100% rename from test/Benchmarks/src/Vector.enso rename to test/Benchmarks/src/Vector/Vector.enso