[wasm][bench] Limit initial samples (#86953)
authorRadek Doulik <radek.doulik@gmail.com>
Wed, 31 May 2023 14:25:35 +0000 (16:25 +0200)
committerGitHub <noreply@github.com>
Wed, 31 May 2023 14:25:35 +0000 (16:25 +0200)
* [wasm][bench] Limit initial samples

Try to limit initial samples measurement to 1 second.

Currently some of string measurements with hybrid globalization turned on
can take hundreds of seconds. This makes the browser stop the benchmark
and the measurement job times out.

This should limit the initial samples to take cca 1 second or take just
one initial sample if it takes more time.

Also increase the initial samples for string comparison, where it was on
the edge and the times were flipping between cca 5 and 10 seconds.

* Do GC collect only when doing initial samples

src/mono/sample/wasm/browser-bench/BenchTask.cs
src/mono/sample/wasm/browser-bench/String.cs
src/mono/sample/wasm/browser-bench/WebSocket.cs

index d9da450..6a41030 100644 (file)
@@ -59,15 +59,16 @@ public abstract class BenchTask
 
         public virtual bool HasRunStepAsync => false;
 
-        protected virtual int CalculateSteps(int milliseconds, TimeSpan initTs)
+        protected virtual int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
         {
-            return (int)(milliseconds * InitialSamples / Math.Max(1.0, initTs.TotalMilliseconds));
+            return (int)(milliseconds * initialSamples / Math.Max(1.0, initTs.TotalMilliseconds));
         }
 
         public async Task<Result> RunBatch(BenchTask task, int milliseconds)
         {
             DateTime start = DateTime.Now;
             DateTime end;
+            int initialSamples = InitialSamples;
             try
             {
                 // run one to eliminate possible startup overhead and do GC collection
@@ -79,15 +80,35 @@ public abstract class BenchTask
                 GC.Collect();
 
                 start = DateTime.Now;
-                for (currentStep = 0; currentStep < InitialSamples; currentStep++)
-                    if (HasRunStepAsync)
-                        await RunStepAsync();
-                    else
-                        RunStep();
+                if (HasRunStepAsync)
+                    await RunStepAsync();
+                else
+                    RunStep();
                 end = DateTime.Now;
 
+                // try to limit initial samples to 1s
+                var oneTs = end - start;
+                var maxInitMs = 1000;
+                if (oneTs.TotalMilliseconds > 0 && oneTs.TotalMilliseconds*InitialSamples > maxInitMs)
+                    initialSamples = (int)(maxInitMs/oneTs.TotalMilliseconds);
+
+                if (initialSamples > 1) {
+                    GC.Collect();
+
+                    start = DateTime.Now;
+                    for (currentStep = 0; currentStep < initialSamples; currentStep++)
+                        if (HasRunStepAsync)
+                            await RunStepAsync();
+                        else
+                            RunStep();
+                    end = DateTime.Now;
+                } else {
+                    // we already have the 1st measurement
+                    initialSamples = 1;
+                }
+
                 var initTs = end - start;
-                int steps = CalculateSteps(milliseconds, initTs);
+                int steps = CalculateSteps(milliseconds, initTs, initialSamples);
 
                 start = DateTime.Now;
                 for (currentStep = 0; currentStep < steps; currentStep++)
@@ -101,14 +122,14 @@ public abstract class BenchTask
 
                 var ts = end - start;
 
-                return new Result { span = ts + initTs, steps = steps + InitialSamples, taskName = task.Name, measurementName = Name };
+                return new Result { span = ts + initTs, steps = steps + initialSamples, taskName = task.Name, measurementName = Name };
             }
             catch (Exception ex)
             {
                 end = DateTime.Now;
                 var ts = end - start;
                 Console.WriteLine(ex);
-                return new Result { span = ts, steps = currentStep + InitialSamples, taskName = task.Name, measurementName = Name + " " + ex.Message };
+                return new Result { span = ts, steps = currentStep + initialSamples, taskName = task.Name, measurementName = Name + " " + ex.Message };
             }
         }
     }
index 2ac38b4..224604f 100644 (file)
@@ -139,6 +139,8 @@ namespace Sample
 
         public abstract class StringsCompare : StringMeasurement
         {
+            public override int InitialSamples => 100;
+
             protected string strAsciiSuffix;
             protected string strAsciiPrefix;
             protected string needleSameAsStrEnd;
index d163537..9cc16ee 100644 (file)
@@ -88,7 +88,7 @@ namespace Sample
             public override int InitialSamples => 1000;
             ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1]);
 
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
                 return 250_000;
             }
@@ -112,7 +112,7 @@ namespace Sample
                     buffer[i] = (byte)(i & 0xff);
                 }
             }
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
                 return 3000;
             }
@@ -137,7 +137,7 @@ namespace Sample
                     buffer[i] = (byte)(i & 0xff);
                 }
             }
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
                 return 100;
             }
@@ -154,9 +154,9 @@ namespace Sample
         {
             ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1]);
 
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
-                return MaxLength - InitialSamples - 100;
+                return MaxLength - initialSamples - 100;
             }
 
             public override void RunStep()
@@ -177,7 +177,7 @@ namespace Sample
             public override int InitialSamples => 1;
             ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[bufferSize]);
 
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
                 return 500;
             }
@@ -206,7 +206,7 @@ namespace Sample
             public override int InitialSamples => 1;
             ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[bufferSize]);
 
-            protected override int CalculateSteps(int milliseconds, TimeSpan initTs)
+            protected override int CalculateSteps(int milliseconds, TimeSpan initTs, int initialSamples)
             {
                 return MaxMessages - 1;
             }