e82711f73e
* Add fast path if string is empty (`length == 0`) * Add fast path (less allocations) for short string (`stackalloc`) * Use `Marshal.AllocHGlobal` * we were the only consumer of `Marshal.AllocCoTaskMem` and `FreeCoTaskMem` (inside most apps) so those symbols can now be removed * `Marshal.AllocCoTaskMem` simply calls `AllocHGlobal` (with some extra casts) so it does not really have any other impact * Add a few `CFString.FromHandle`` performance tests To cover cases for * `nil` which returns `null` * `128` characters, which is the limit for `stackalloc` * `129` characters, which is just over the limit for `stackalloc` **Expectations** * `empty` should be faster, since it now returns earlier * `short_*` and `stackalloc_limit` should be a bit faster as they use `stackalloc` * `allochglobal` and `long_string` should be (nearly) identical **Before** | Method | name | Mean | Error | StdDev | |-------------------- |----------------- |-------------:|------------:|-----------:| | CFString_FromString | allochglobal | 547.765 ns | 245.5782 ns | 13.4610 ns | | CFString_FromString | empty | 377.983 ns | 6.7926 ns | 0.3723 ns | | CFString_FromString | long_string | 5,480.664 ns | 264.9473 ns | 14.5227 ns | | CFString_FromString | nil | 4.848 ns | 0.0412 ns | 0.0023 ns | | CFString_FromString | short_7bits | 442.096 ns | 30.4907 ns | 1.6713 ns | | CFString_FromString | short_accent | 221.221 ns | 2.2069 ns | 0.1210 ns | | CFString_FromString | short_emoji | 221.870 ns | 2.4471 ns | 0.1341 ns | | CFString_FromString | short_unicode | 217.954 ns | 1.8771 ns | 0.1029 ns | | CFString_FromString | stackalloc_limit | 484.019 ns | 6.3940 ns | 0.3505 ns | **After** | Method | name | Mean | Error | StdDev | |-------------------- |----------------- |-------------:|------------:|-----------:| | CFString_FromString | allochglobal | 554.028 ns | 317.1811 ns | 17.3858 ns | | CFString_FromString | empty | 95.442 ns | 7.6434 ns | 0.4190 ns | | CFString_FromString | long_string | 5,468.565 ns | 251.2252 ns | 13.7705 ns | | CFString_FromString | nil | 3.299 ns | 0.0229 ns | 0.0013 ns | | CFString_FromString | short_7bits | 352.567 ns | 25.7539 ns | 1.4117 ns | | CFString_FromString | short_accent | 221.132 ns | 0.9760 ns | 0.0535 ns | | CFString_FromString | short_emoji | 222.557 ns | 4.5978 ns | 0.2520 ns | | CFString_FromString | short_unicode | 216.375 ns | 5.1619 ns | 0.2829 ns | | CFString_FromString | stackalloc_limit | 427.663 ns | 77.9610 ns | 4.2733 ns | |
||
---|---|---|
.. | ||
Assets.xcassets | ||
dotnet | ||
legacy | ||
.gitignore | ||
AppDelegate.cs | ||
Entitlements.plist | ||
Info.plist | ||
Main.cs | ||
Main.storyboard | ||
Makefile | ||
ManagedRuntime.cs | ||
MessageSend.cs | ||
Messaging.cs | ||
NativeArrayPerf.cs | ||
ObjCBridge.cs | ||
ObjectCreation.cs | ||
README.md | ||
TollFreeBridge.cs | ||
ViewController.cs | ||
ViewController.designer.cs | ||
perftest.sln |
README.md
Benchmarks
This folder contains a test suite to test performance in Xamarin.iOS/Xamarin.Mac.
There are three variations of the test suite:
-
Legacy mode (Xamarin).
-
.NET Mode (Mono): runs tests in .NET, with MonoVM.
-
.NET Mode (CoreCLR): runs tests using .NET, with CoreCLR.
Running the benchmarks
Run all three variations of the test suite:
make run-perftest
Run each variation:
Legacy mode
make run-perftest-with-legacy
.NET Mode (Mono)
make run-perftest-with-mono
.NET Mode (CoreCLR)
make run-perftest-with-coreclr
Results
At the end of the test run, something like this will be printed:
Log files were stored in xamarin-macios/tests/perftest/output/2021-04-22--21:43:28
and that's where you'll find log files. Console output from the executable is stored as perflog-[timestamp].log, while BenchmarkDotNet results are exported to the results/ subfolder (in json, markdown, csv and html formats).
There's no easy way to compare results across variations or runs (yet), the exported results will have to be examined by a human and compared that way.