xamarin-macios/tests/perftest
Sebastien Pouliot 0649960dc3
Use `CFString` instead of `NSString` to get a handle from a (.net) `System.String` (#11946)
This is possible because both types are toll-free bridged [0].

How ?

* Renamed `CFString.LowLevelCreate` to `CreateNative` so it match `NSString` API
* Make it public so it can be used for generated/3rd party bindings
* Added a _safe_ `CFString.ReleaseNative` matching `NSString` API
* Update generator to use the new API (instead of the NSString version)
* Update manual bindings (using older API) to use the new API (few in PrintCore)

Why ?

It's no secret that p/invoke (C) are faster than calling a selector
(ObjC). In most cases we do not have a choice what to call... but in a
few, but commonly used, cases we can pick the fastest call.

In this case the difference is larger than the previous case [1] since there's
two call (create and release) involved.

|                 Method |          name |                value |        Mean |       Error |    StdDev |
|----------------------- |-------------- |--------------------- |------------:|------------:|----------:|
| NSString_CreateRelease |         empty |                      |  4,936.1 ns |   349.08 ns |  19.13 ns |
| CFString_CreateRelease |         empty |                      |    243.1 ns |    10.30 ns |   0.56 ns |
| NSString_CreateRelease |   long_string | ????(...)???? [4096] |  8,270.3 ns |   837.09 ns |  45.88 ns |
| CFString_CreateRelease |   long_string | ????(...)???? [4096] |  3,212.4 ns |   213.73 ns |  11.72 ns |
| NSString_CreateRelease |   short_7bits |              Bonjour |  4,858.5 ns | 1,671.67 ns |  91.63 ns |
| CFString_CreateRelease |   short_7bits |              Bonjour |    242.5 ns |    18.36 ns |   1.01 ns |
| NSString_CreateRelease |  short_accent |               Québec |  4,990.1 ns |   343.96 ns |  18.85 ns |
| CFString_CreateRelease |  short_accent |               Québec |    377.6 ns |    15.96 ns |   0.87 ns |
| NSString_CreateRelease |   short_emoji | I'm f(...)ight. [23] |  5,080.2 ns |   794.29 ns |  43.54 ns |
| CFString_CreateRelease |   short_emoji | I'm f(...)ight. [23] |    391.2 ns |     8.60 ns |   0.47 ns |
| NSString_CreateRelease | short_unicode |                汉语 漢語 |  4,980.4 ns |   272.41 ns |  14.93 ns |
| CFString_CreateRelease | short_unicode |                汉语 漢語 |    376.4 ns |    15.98 ns |   0.88 ns |

Also simplified/updated previous tests as suggested in [1].

|                 Method |          name |                value |        Mean |       Error |    StdDev |
|----------------------- |-------------- |--------------------- |------------:|------------:|----------:|
|    NSString_FromString |         empty |      140735350713040 |  2,252.2 ns |   591.63 ns |  32.43 ns |
|    CFString_FromString |         empty |      140735350713040 |    408.4 ns |    47.56 ns |   2.61 ns |
|    NSString_FromString |   long_string |      140295885995872 | 14,887.2 ns |   183.67 ns |  10.07 ns |
|    CFString_FromString |   long_string |      140295885995872 |  7,418.7 ns | 1,844.42 ns | 101.10 ns |
|    NSString_FromString |   short_7bits |  1292713981587835779 |  2,259.8 ns |   210.17 ns |  11.52 ns |
|    CFString_FromString |   short_7bits |  1292713981587835779 |    453.0 ns |   122.77 ns |   6.73 ns |
|    NSString_FromString |  short_accent |      140295885995776 |  2,448.2 ns |    97.43 ns |   5.34 ns |
|    CFString_FromString |  short_accent |      140295885995776 |    256.8 ns |    75.81 ns |   4.16 ns |
|    NSString_FromString |   short_emoji |      140296423669120 |  2,531.6 ns |   199.02 ns |  10.91 ns |
|    CFString_FromString |   short_emoji |      140296423669120 |    259.0 ns |    21.32 ns |   1.17 ns |
|    NSString_FromString | short_unicode |      140295885992304 |  2,426.2 ns |   339.06 ns |  18.58 ns |
|    CFString_FromString | short_unicode |      140295885992304 |    260.6 ns |    97.03 ns |   5.32 ns |

[1] https://github.com/xamarin/xamarin-macios/pull/11809
2021-06-16 14:11:38 -04:00
..
Assets.xcassets [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
dotnet [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
legacy [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
.gitignore [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
AppDelegate.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Entitlements.plist [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Info.plist [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Main.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Main.storyboard [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Makefile [dotnet] Remove the .NET workload resolver workaround, it's not needed anymore. (#11695) 2021-05-27 07:30:46 +02:00
MessageSend.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
Messaging.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
ObjCBridge.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
ObjectCreation.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
README.md [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
TollFreeBridge.cs Use `CFString` instead of `NSString` to get a handle from a (.net) `System.String` (#11946) 2021-06-16 14:11:38 -04:00
ViewController.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
ViewController.designer.cs [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00
perftest.sln [tests] Add a performance test using BenchmarkDotNet. (#11298) 2021-04-23 13:29:06 +02:00

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.