Added lol benchmark
This commit is contained in:
Родитель
055b2e910e
Коммит
0ab6ff39c7
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
|
||||
namespace AlohaKit.UI.Gallery.Helpers
|
||||
{
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: Random
|
||||
**
|
||||
**
|
||||
** Purpose: A random number generator.
|
||||
**
|
||||
**
|
||||
===========================================================*/
|
||||
|
||||
/// <summary>
|
||||
/// To have consistent behaviour of random generator across Runtimes (Mono, Core) and avoid changes to it in future releases src from Github repo is used instead of stock BCL class.
|
||||
/// </summary>
|
||||
public class Random2
|
||||
{
|
||||
//
|
||||
// Private Constants
|
||||
//
|
||||
private const int MBIG = 2000000000;
|
||||
private const int MSEED = 161803398;
|
||||
|
||||
//
|
||||
// Member Variables
|
||||
//
|
||||
private int inext;
|
||||
private int inextp;
|
||||
private int[] SeedArray = new int[56];
|
||||
|
||||
//
|
||||
// Public Constants
|
||||
//
|
||||
|
||||
//
|
||||
// Native Declarations
|
||||
//
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
public Random2(int Seed)
|
||||
{
|
||||
int ii;
|
||||
int mj, mk;
|
||||
|
||||
//Initialize our Seed array.
|
||||
//This algorithm comes from Numerical Recipes in C (2nd Ed.)
|
||||
int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed);
|
||||
mj = MSEED - subtraction;
|
||||
SeedArray[55] = mj;
|
||||
mk = 1;
|
||||
for (int i = 1; i < 55; i++)
|
||||
{ //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
|
||||
ii = (21 * i) % 55;
|
||||
SeedArray[ii] = mk;
|
||||
mk = mj - mk;
|
||||
if (mk < 0) mk += MBIG;
|
||||
mj = SeedArray[ii];
|
||||
}
|
||||
for (int k = 1; k < 5; k++)
|
||||
{
|
||||
for (int i = 1; i < 56; i++)
|
||||
{
|
||||
SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
|
||||
if (SeedArray[i] < 0) SeedArray[i] += MBIG;
|
||||
}
|
||||
}
|
||||
inext = 0;
|
||||
inextp = 21;
|
||||
}
|
||||
|
||||
//
|
||||
// Package Private Methods
|
||||
//
|
||||
|
||||
/*====================================Sample====================================
|
||||
**Action: Return a new random number [0..1) and reSeed the Seed array.
|
||||
**Returns: A double [0..1)
|
||||
**Arguments: None
|
||||
**Exceptions: None
|
||||
==============================================================================*/
|
||||
protected virtual double Sample()
|
||||
{
|
||||
//Including this division at the end gives us significantly improved
|
||||
//random number distribution.
|
||||
return (InternalSample() * (1.0 / MBIG));
|
||||
}
|
||||
|
||||
private int InternalSample()
|
||||
{
|
||||
int retVal;
|
||||
int locINext = inext;
|
||||
int locINextp = inextp;
|
||||
|
||||
if (++locINext >= 56) locINext = 1;
|
||||
if (++locINextp >= 56) locINextp = 1;
|
||||
|
||||
retVal = SeedArray[locINext] - SeedArray[locINextp];
|
||||
|
||||
if (retVal == MBIG) retVal--;
|
||||
if (retVal < 0) retVal += MBIG;
|
||||
|
||||
SeedArray[locINext] = retVal;
|
||||
|
||||
inext = locINext;
|
||||
inextp = locINextp;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//
|
||||
// Public Instance Methods
|
||||
//
|
||||
|
||||
/*=====================================Next=====================================
|
||||
**Returns: A double [0..1)
|
||||
**Arguments: None
|
||||
**Exceptions: None
|
||||
==============================================================================*/
|
||||
public virtual double NextDouble()
|
||||
{
|
||||
return Sample();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="AlohaKit.UI.Gallery.Views.LolBenchmarkPage"
|
||||
xmlns:alohakit="clr-namespace:AlohaKit.UI;assembly=AlohaKit.UI"
|
||||
Title="AlohaKit UI LOL's Benchmark">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="60" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<alohakit:CanvasView
|
||||
x:Name="CanvasView"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0" />
|
||||
<Grid
|
||||
x:Name="GridLayout"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
<Label
|
||||
x:Name="LolLabel"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
Margin="0,20,0,0"
|
||||
Padding="7,7,7,7"
|
||||
BackgroundColor="Red"
|
||||
TextColor="White"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
Text="Warming up..."
|
||||
IsVisible="False"/>
|
||||
<HorizontalStackLayout
|
||||
x:Name="ButtonsLayout"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalOptions="End"
|
||||
HorizontalOptions="Center"
|
||||
Margin="6">
|
||||
<Button
|
||||
x:Name="StopButton"
|
||||
Text="Stop"
|
||||
BackgroundColor="Red"
|
||||
HorizontalOptions="Center"
|
||||
IsVisible="False"
|
||||
Clicked="OnStopButtonClicked"/>
|
||||
<Button
|
||||
x:Name="StartButton"
|
||||
Text="Start"
|
||||
BackgroundColor="Green"
|
||||
Clicked="OnStartButtonClicked"/>
|
||||
</HorizontalStackLayout>
|
||||
</Grid>
|
||||
</ContentPage>
|
|
@ -0,0 +1,148 @@
|
|||
using System.Diagnostics;
|
||||
using AlohaKit.UI.Gallery.Helpers;
|
||||
|
||||
namespace AlohaKit.UI.Gallery.Views;
|
||||
|
||||
public partial class LolBenchmarkPage : ContentPage
|
||||
{
|
||||
public LolBenchmarkPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
volatile bool breakTest = false;
|
||||
const int Max = 500;
|
||||
|
||||
void StartTestCanvasView()
|
||||
{
|
||||
var rand = new Random2(0);
|
||||
|
||||
breakTest = false;
|
||||
|
||||
var width = CanvasView.Width;
|
||||
var height = CanvasView.Height;
|
||||
|
||||
const int step = 20;
|
||||
var labels = new Label[step * 2];
|
||||
|
||||
var processed = 0;
|
||||
|
||||
long prevTicks = 0;
|
||||
long prevMs = 0;
|
||||
int prevProcessed = 0;
|
||||
double avgSum = 0;
|
||||
int avgN = 0;
|
||||
var sw = new Stopwatch();
|
||||
|
||||
Action loop = null;
|
||||
|
||||
loop = () =>
|
||||
{
|
||||
var now = sw.ElapsedMilliseconds;
|
||||
|
||||
if (breakTest)
|
||||
{
|
||||
var avg = avgSum / avgN;
|
||||
LolLabel.Text = string.Format("{0:0.00} LOL/s (AVG)", avg).PadLeft(21);
|
||||
return;
|
||||
}
|
||||
|
||||
// 60hz, 16ms to build the frame
|
||||
while (sw.ElapsedMilliseconds - now < 16)
|
||||
{
|
||||
var label = new Label()
|
||||
{
|
||||
Text = "lol?",
|
||||
TextColor = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble()),
|
||||
Rotation = (float)rand.NextDouble() * 360
|
||||
};
|
||||
|
||||
label.X = (float)(rand.NextDouble() * width);
|
||||
label.Y = (float)(rand.NextDouble() * height);
|
||||
label.WidthRequest = 80f;
|
||||
label.HeightRequest = 24f;
|
||||
|
||||
if (processed > Max)
|
||||
{
|
||||
CanvasView.Children.RemoveAt(0);
|
||||
}
|
||||
|
||||
CanvasView.Children.Add(label);
|
||||
CanvasView.Invalidate();
|
||||
|
||||
processed++;
|
||||
|
||||
if (sw.ElapsedMilliseconds - prevMs > 500)
|
||||
{
|
||||
|
||||
var r = (processed - prevProcessed) / ((double)(sw.ElapsedTicks - prevTicks) / Stopwatch.Frequency);
|
||||
prevTicks = sw.ElapsedTicks;
|
||||
prevProcessed = processed;
|
||||
|
||||
if (processed > Max)
|
||||
{
|
||||
LolLabel.Text = string.Format("{0:0.00} LOL/s", r).PadLeft(15);
|
||||
avgSum += r;
|
||||
avgN++;
|
||||
}
|
||||
|
||||
prevMs = sw.ElapsedMilliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
Dispatcher.Dispatch(loop);
|
||||
};
|
||||
|
||||
sw.Start();
|
||||
|
||||
loop();
|
||||
}
|
||||
|
||||
|
||||
void SetControlsAtStart()
|
||||
{
|
||||
StartButton.IsVisible = false;
|
||||
StopButton.IsVisible = LolLabel.IsVisible = true;
|
||||
CanvasView.Children.Clear();
|
||||
GridLayout.Children.Clear();
|
||||
LolLabel.Text = "Warming up...";
|
||||
}
|
||||
|
||||
void OnStopButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
breakTest = true;
|
||||
StopButton.IsVisible = false;
|
||||
StartButton.IsVisible = true;
|
||||
}
|
||||
|
||||
async void OnStartButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
int testLengthMs = 60000;
|
||||
int pauseLengthMs = 100;
|
||||
|
||||
SetControlsAtStart();
|
||||
StartTestCanvasView();
|
||||
|
||||
await Task.Delay(testLengthMs);
|
||||
OnStopButtonClicked(default, default);
|
||||
await Task.Delay(pauseLengthMs);
|
||||
_ = decimal.TryParse(LolLabel.Text.Replace(" LOL/s (AVG)", "").Trim(), out var resultST);
|
||||
|
||||
var platformVersion = "AlohaKit UI";
|
||||
|
||||
#if ANDROID
|
||||
var operatingSystem = "Android";
|
||||
#elif IOS
|
||||
var operatingSystem = "iOS";
|
||||
#elif MACCATALYST
|
||||
var operatingSystem = "MacCatalyst";
|
||||
#elif WINDOWS
|
||||
var operatingSystem = "WinUI";
|
||||
#else
|
||||
var operatingSystem = "Unknown";
|
||||
#endif
|
||||
|
||||
var results = new { OS = operatingSystem, Platform = platformVersion, Build = resultST, Reuse = 0, Grid = 0 };
|
||||
LolLabel.Text = $"Build: {results.Build}";
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@
|
|||
<Button
|
||||
Text="Custom Drawn Controls"
|
||||
Clicked="OnCustomControlsButtonClicked"/>
|
||||
<Button
|
||||
Text="LOL/s Benchmark"
|
||||
Clicked="OnBenchmarkButtonClicked"/>
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
|
@ -20,6 +20,11 @@
|
|||
void OnCustomControlsButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
Navigation.PushAsync(new CustomControlsPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnBenchmarkButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
Navigation.PushAsync(new LolBenchmarkPage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,7 +85,7 @@ namespace AlohaKit.UI
|
|||
}
|
||||
|
||||
canvas.Alpha = (float)Opacity;
|
||||
canvas.Transform(TranslationX, TranslationY, ScaleX, ScaleY);
|
||||
canvas.Transform(Rotation, TranslationX, TranslationY, ScaleX, ScaleY);
|
||||
|
||||
DrawShadow(canvas, bounds);
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace AlohaKit.UI
|
||||
using Microsoft.Maui.Devices.Sensors;
|
||||
|
||||
namespace AlohaKit.UI
|
||||
{
|
||||
public interface IVisualElement
|
||||
{
|
||||
|
@ -52,6 +54,10 @@
|
|||
BindableProperty.Create(nameof(Shadow), typeof(Shadow), typeof(VisualElement), null,
|
||||
propertyChanged: InvalidatePropertyChanged);
|
||||
|
||||
public static readonly BindableProperty RotationProperty =
|
||||
BindableProperty.Create(nameof(Rotation), typeof(float), typeof(VisualElement), 0f,
|
||||
propertyChanged: InvalidatePropertyChanged);
|
||||
|
||||
public static readonly BindableProperty TranslationXProperty =
|
||||
BindableProperty.Create(nameof(TranslationX), typeof(float), typeof(VisualElement), 0f,
|
||||
propertyChanged: InvalidatePropertyChanged);
|
||||
|
@ -113,6 +119,12 @@
|
|||
set => SetValue(ShadowProperty, value);
|
||||
}
|
||||
|
||||
public float Rotation
|
||||
{
|
||||
get => (float)GetValue(RotationProperty);
|
||||
set => SetValue(RotationProperty, value);
|
||||
}
|
||||
|
||||
public float TranslationX
|
||||
{
|
||||
get => (float)GetValue(TranslationXProperty);
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
{
|
||||
public static class CanvasExtensions
|
||||
{
|
||||
public static void Transform(this ICanvas canvas, float tX, float tY, float sX, float sY)
|
||||
public static void Transform(this ICanvas canvas, float rotation, float tX, float tY, float sX, float sY)
|
||||
{
|
||||
canvas.Rotate(rotation);
|
||||
canvas.Translate(tX, tY);
|
||||
canvas.Scale(sX, sY);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче