A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.IO;
4using Unity.PerformanceTesting.Exceptions;
5using UnityEngine;
6
7namespace Unity.PerformanceTesting.Runtime
8{
9 internal static class Utils
10 {
11 public static string ResourcesPath => Path.Combine(Application.dataPath, "Resources");
12 public const string TestRunPath = "Assets/Resources/" + TestRunInfo;
13 public const string TestRunInfo = "PerformanceTestRunInfo.json";
14 public const string PlayerPrefKeyRunJSON = "PT_Run";
15 public const string RunSettingsPath = "Assets/Resources/" + RunSettings;
16 public const string RunSettings = "PerformanceTestRunSettings.json";
17 public const string PlayerPrefKeySettingsJSON = "PT_Settings";
18
19 public static DateTime ConvertFromUnixTimestamp(long timestamp)
20 {
21 var offset = DateTimeOffset.FromUnixTimeMilliseconds(timestamp);
22 return offset.UtcDateTime;
23 }
24
25 public static long ConvertToUnixTimestamp(DateTime date)
26 {
27 var offset = new DateTimeOffset(date);
28 return offset.ToUnixTimeMilliseconds();
29 }
30
31 public static double ConvertSample(SampleUnit from, SampleUnit to, double value)
32 {
33 if (from.Equals(to)) return value;
34 var ratio = GetRatio(from, to);
35 return value * ratio;
36 }
37
38 public static double GetRatio(SampleUnit from, SampleUnit to)
39 {
40 double f = RelativeSampleUnit(from);
41 double t = RelativeSampleUnit(to);
42 return f / t;
43 }
44
45 public static double RelativeSampleUnit(SampleUnit unit)
46 {
47 switch (unit)
48 {
49 case SampleUnit.Nanosecond:
50 return 1;
51 case SampleUnit.Microsecond:
52 return 1000;
53 case SampleUnit.Millisecond:
54 return 1000000;
55 case SampleUnit.Second:
56 return 1000000000;
57 case SampleUnit.Byte:
58 return 1;
59 case SampleUnit.Kilobyte:
60 return 1000;
61 case SampleUnit.Megabyte:
62 return 1000000;
63 case SampleUnit.Gigabyte:
64 return 1000000000;
65 default:
66 throw new PerformanceTestException(
67 "Wrong SampleUnit type used.");
68 }
69 }
70
71 public static void UpdateStatistics(this SampleGroup sampleGroup)
72 {
73 if (sampleGroup.Samples == null) return;
74 var samples = sampleGroup.Samples;
75 if (samples.Count < 2)
76 {
77 sampleGroup.Min = samples[0];
78 sampleGroup.Max = samples[0];
79 sampleGroup.Median = samples[0];
80 sampleGroup.Average = samples[0];
81 sampleGroup.Sum = samples[0];
82 sampleGroup.StandardDeviation = 0;
83 }
84 else
85 {
86 sampleGroup.Min = Utils.Min(samples);
87 sampleGroup.Max = Utils.Max(samples);
88 sampleGroup.Median = Utils.GetMedianValue(samples);
89 sampleGroup.Average = Utils.Average(samples);
90 sampleGroup.Sum = Utils.Sum(samples);
91 sampleGroup.StandardDeviation = Utils.GetStandardDeviation(samples, sampleGroup.Average);
92 }
93 }
94
95 public static int GetZeroValueCount(List<double> samples)
96 {
97 var zeroValues = 0;
98 foreach (var sample in samples)
99 {
100 if (Math.Abs(sample) < .0001f)
101 {
102 zeroValues++;
103 }
104 }
105
106 return zeroValues;
107 }
108
109 public static double GetMedianValue(List<double> samples)
110 {
111 var samplesClone = new List<double>(samples);
112 var middleIndex = samplesClone.Count / 2;
113 samplesClone.Sort();
114
115 return samplesClone.Count % 2 != 0
116 ? samplesClone[middleIndex]
117 : (samplesClone[middleIndex - 1] + samplesClone[middleIndex]) / 2.0;
118 }
119
120 public static double GetPercentile(List<double> samples, double percentile)
121 {
122 if (percentile < 0.00001D)
123 return percentile;
124
125 var samplesClone = new List<double>(samples);
126 samplesClone.Sort();
127
128 if (samplesClone.Count == 1)
129 {
130 return samplesClone[0];
131 }
132
133 var rank = percentile * (samplesClone.Count + 1);
134 var integral = (int)rank;
135 var fractional = rank % 1;
136 return samplesClone[integral - 1] + fractional * (samplesClone[integral] - samplesClone[integral - 1]);
137 }
138
139 public static double GetStandardDeviation(List<double> samples, double average)
140 {
141 double sumOfSquaresOfDifferences = 0.0D;
142 foreach (var sample in samples)
143 {
144 sumOfSquaresOfDifferences += (sample - average) * (sample - average);
145 }
146
147 return Math.Sqrt(sumOfSquaresOfDifferences / samples.Count);
148 }
149
150 public static double Min(List<double> samples)
151 {
152 double min = Mathf.Infinity;
153 foreach (var sample in samples)
154 {
155 if (sample < min) min = sample;
156 }
157
158 return min;
159 }
160
161 public static double Max(List<double> samples)
162 {
163 double max = Mathf.NegativeInfinity;
164 foreach (var sample in samples)
165 {
166 if (sample > max) max = sample;
167 }
168
169 return max;
170 }
171
172 public static double Average(List<double> samples)
173 {
174 return Sum(samples) / samples.Count;
175 }
176
177 public static double Sum(List<double> samples)
178 {
179 double sum = 0.0D;
180 foreach (var sample in samples)
181 {
182 sum += sample;
183 }
184
185 return sum;
186 }
187
188 public static string RemoveIllegalCharacters(string path)
189 {
190 string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
191
192 foreach (char c in invalid)
193 {
194 path = path.Replace(c.ToString(), "");
195 }
196
197 return path;
198 }
199
200 public static string GetArg(string[] args, string name)
201 {
202 for (int i = 0; i < args.Length; i++)
203 {
204 if (args[i] == name && args.Length > i + 1)
205 {
206 return args[i + 1];
207 }
208 }
209
210 return null;
211 }
212
213 internal static int ToInt(this string s)
214 {
215 if (int.TryParse(s, out var i)) return i;
216 return -1;
217 }
218
219 internal static SampleGroup[] CreateSampleGroupsFromMarkerNames(params string[] profilerMarkerNames)
220 {
221 if (profilerMarkerNames == null) return new List<SampleGroup>().ToArray();
222 var sampleGroups = new List<SampleGroup>();
223 foreach (var marker in profilerMarkerNames)
224 {
225 sampleGroups.Add(new SampleGroup(marker, SampleUnit.Nanosecond, false));
226 }
227
228 return sampleGroups.ToArray();
229 }
230 }
231}