A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using System.Diagnostics;
6using System.Reflection;
7using BenchmarkDotNet.Attributes;
8using NUnit.Framework;
9using osu.Framework.Graphics.Sprites;
10using osu.Framework.IO.Stores;
11using osu.Framework.Testing;
12using SixLabors.ImageSharp.Memory;
13
14namespace osu.Framework.Benchmarks
15{
16 public class BenchmarkFontLoading : BenchmarkTest
17 {
18 private NamespacedResourceStore<byte[]> baseResources;
19 private TemporaryNativeStorage sharedTemp;
20
21 public override void SetUp()
22 {
23 SixLabors.ImageSharp.Configuration.Default.MemoryAllocator = ArrayPoolMemoryAllocator.CreateDefault();
24
25 baseResources = new NamespacedResourceStore<byte[]>(new DllResourceStore(@"osu.Framework.dll"), @"Resources");
26 sharedTemp = new TemporaryNativeStorage("fontstore-test-" + Guid.NewGuid());
27 }
28
29 [OneTimeTearDown]
30 public void TearDown()
31 {
32 sharedTemp?.Dispose();
33 }
34
35 [Params(1, 10, 100, 1000, 10000)]
36 public int FetchCount;
37
38 private const string font_name = @"Fonts/FontAwesome5/FontAwesome-Solid";
39
40 [Benchmark]
41 public void BenchmarkRawCachingReuse()
42 {
43 using (var store = new RawCachingGlyphStore(baseResources, font_name) { CacheStorage = sharedTemp })
44 runFor(store);
45 }
46
47 [Benchmark(Baseline = true)]
48 public void BenchmarkRawCaching()
49 {
50 using (var temp = new TemporaryNativeStorage("fontstore-test" + Guid.NewGuid()))
51 using (var store = new RawCachingGlyphStore(baseResources, font_name) { CacheStorage = temp })
52 runFor(store);
53 }
54
55 [Benchmark]
56 public void BenchmarkNoCache()
57 {
58 if (FetchCount > 100) // gets too slow.
59 throw new NotImplementedException();
60
61 using (var store = new GlyphStore(baseResources, font_name))
62 runFor(store);
63 }
64
65 [Benchmark]
66 public void BenchmarkTimedExpiry()
67 {
68 SixLabors.ImageSharp.Configuration.Default.MemoryAllocator = ArrayPoolMemoryAllocator.CreateDefault();
69
70 using (var store = new TimedExpiryGlyphStore(baseResources, font_name))
71 runFor(store);
72 }
73
74 [Benchmark]
75 public void BenchmarkTimedExpiryMemoryPooling()
76 {
77 using (var store = new TimedExpiryGlyphStore(baseResources, font_name))
78 runFor(store);
79 }
80
81 private void runFor(GlyphStore store)
82 {
83 store.LoadFontAsync().Wait();
84
85 var props = typeof(FontAwesome.Solid).GetProperties(BindingFlags.Public | BindingFlags.Static);
86
87 int remainingCount = FetchCount;
88
89 while (true)
90 {
91 foreach (var p in props)
92 {
93 var propValue = p.GetValue(null);
94 Debug.Assert(propValue != null);
95
96 var icon = (IconUsage)propValue;
97 using (var upload = store.Get(icon.Icon.ToString()))
98 Trace.Assert(upload.Data != null);
99
100 if (remainingCount-- == 0)
101 return;
102 }
103 }
104 }
105 }
106}