Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/PathBench/MethodProfileReportFormatter.Graphviz.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ public static string SanitizeIdentifier(string name)
{
var sb = new StringBuilder();
sb.Append("__");
foreach (var c in name.EnumerateRunes())
foreach (var c in name)
{
switch (c.Value)
switch (c)
{
case >= 0x30 and < 0x3A:
case >= 0x41 and < 0x5B:
case >= 0x61 and < 0x7B:
case >= (char)0x30 and < (char)0x3A:
case >= (char)0x41 and < (char)0x5B:
case >= (char)0x61 and < (char)0x7B:
sb.Append(c);
continue;
default:
sb.Append($"_u{(uint)c.Value:X04}_");
sb.Append($"_u{(uint)c:X04}_");
continue;
}
}
Expand All @@ -106,9 +106,9 @@ public static string SanitizeIdentifier(string name)
public static string SanitizeLabel(string name)
{
var sb = new StringBuilder(name.Length * 2);
foreach (var c in name.EnumerateRunes())
foreach (var c in name)
{
switch (c.Value)
switch (c)
{
case '\n':
sb.Append(@"\n");
Expand Down
11 changes: 10 additions & 1 deletion src/PathBench/PathBench.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!--<TargetFramework>net10.0</TargetFramework>-->
<TargetFrameworks>net10.0;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>

Expand All @@ -25,4 +26,12 @@
<None Include="../../readme.md" Pack="true" PackagePath="" />
<None Include="../../LICENSE.txt" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="System.Collections.Immutable" Version="10.0.9" />
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="10.0.9" />
</ItemGroup>

<ItemGroup>
</ItemGroup>
</Project>
14 changes: 12 additions & 2 deletions src/PathBench/PreciseDuration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if NET7_0_OR_GREATER
using System.Numerics;
#endif
using System.Text.RegularExpressions;

namespace PathBench;
Expand All @@ -9,9 +11,11 @@ namespace PathBench;
public readonly partial struct PreciseDuration(long ticks)
: IEquatable<PreciseDuration>
, IComparable<PreciseDuration>
#if NET7_0_OR_GREATER
, IComparisonOperators<PreciseDuration, PreciseDuration, bool>
, IAdditionOperators<PreciseDuration, PreciseDuration, PreciseDuration>
, ISubtractionOperators<PreciseDuration, PreciseDuration, PreciseDuration>
#endif
, IFormattable
{
/// <summary>
Expand Down Expand Up @@ -202,8 +206,14 @@ public static PreciseDuration FromNanoseconds(double nanoseconds) =>

#region ToString overloads

[GeneratedRegex(@"^(?<real>.+?)(?<unit>nsec|usec|msec|sec|)$")]
//lang=regex
private const string _formatMatchingPattern = @"^(?<real>.+?)(?<unit>nsec|usec|msec|sec|)$";
#if NET7_0_OR_GREATER
[GeneratedRegex(_formatMatchingPattern)]
private static partial Regex GetFormatMatcher();
#else
private static Regex GetFormatMatcher() => new (_formatMatchingPattern, RegexOptions.Compiled);
#endif
private static readonly Regex _FormatMatcher = GetFormatMatcher();

/// <inheritdoc />
Expand Down Expand Up @@ -279,7 +289,7 @@ public string ToString(string? realPartFormat, TimeScale timeScale, IFormatProvi
_ => throw new FormatException("Invalid time scale."),
};

#endregion ToString overloads
#endregion ToString overloads

/// <inheritdoc />
[ExcludeFromCodeCoverage]
Expand Down
111 changes: 111 additions & 0 deletions src/PathBench/__FrameworkCompatibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma warning disable IDE0079 // Remove unnecessary suppression
#pragma warning disable IDE0130 // Namespace does not match folder structure

#if !NET5_0_OR_GREATER
using System.Runtime.CompilerServices;

namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit;
}

namespace System.Runtime.InteropServices
{
internal static class CollectionsMarshal
{
private sealed class ListCompat<T>
{
internal T[]? _items = default; // Do not rename (binary serialization)
internal int _size = default; // Do not rename (binary serialization)
internal int _version = default; // Do not rename (binary serialization)
}

public static ReadOnlySpan<T> AsSpan<T>(List<T>? list)
{
Span<T> span = default;
if (list is not null)
{
var listCompat = Unsafe.As<List<T>, ListCompat<T>>(ref list);
int size = listCompat._size;
T[] items = listCompat._items!;

if ((uint)size > (uint)items.Length)
{
throw new InvalidOperationException();
}

span = items.AsSpan(0, size);
}

return span;
}
}
}
#endif

#if !NET7_0_OR_GREATER
namespace System
{
internal static class TimeSpanExtensions
{
extension(TimeSpan ts)
{
public static long TicksPerMicrosecond => TimeSpan.TicksPerMillisecond / 1000;
}
}
}
#endif

#if !NET9_0_OR_GREATER
namespace System.Threading
{
internal class Lock
{
private sealed class Scope(object token) : IDisposable
{
public void Dispose()
{
Monitor.Exit(token);
}
}

private readonly object _token = new();

internal IDisposable EnterScope()
{
Monitor.Enter(_token);
return new Scope(_token);
}
}
}
#endif

#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP2_0_OR_GREATER
namespace System.Collections.Generic
{
internal static class CollectionExtensions
{
extension<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
public bool TryAdd(TKey key, TValue value)
{
if (dict.ContainsKey(key)) return false;
dict.Add(key, value);
return true;
}
}

extension<TKey, TValue>(KeyValuePair<TKey, TValue> kv)
{
public void Deconstruct(out TKey key, out TValue value)
{
key = kv.Key;
value = kv.Value;
}
}
}
}
#endif

#pragma warning restore IDE0130 // Namespace does not match folder structure
#pragma warning restore IDE0079 // Remove unnecessary suppression
26 changes: 26 additions & 0 deletions tests/PathBench.Test/MethodProfileReportFormatter.GraphvizTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;

namespace PathBench.Test;
Expand All @@ -9,6 +10,8 @@ private static class PrivateAccess
public const string _typeName =
$"{nameof(PathBench)}.{nameof(MethodProfileReportFormatter)}+GraphvizStyle_, PathBench";

#if NET10_0_OR_GREATER

[UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SanitizeIdentifier")]
public extern static string SanitizeIdentifier(
[UnsafeAccessorType(_typeName)] object? _,
Expand All @@ -18,6 +21,29 @@ public extern static string SanitizeIdentifier(
public extern static string SanitizeLabel(
[UnsafeAccessorType(_typeName)] object? _,
string input);

#else
private static readonly Type _GraphvizStyle_ =
typeof(MethodProfileReportFormatter)
.GetNestedType("GraphvizStyle_", BindingFlags.NonPublic)!;

private static readonly MethodInfo _SanitizeIdentifier =
_GraphvizStyle_.GetMethod("SanitizeIdentifier", BindingFlags.Public | BindingFlags.Static)!;

private static readonly MethodInfo _SanitizeLabel =
_GraphvizStyle_.GetMethod("SanitizeLabel", BindingFlags.Public | BindingFlags.Static)!;

public static string SanitizeIdentifier(object? _, string input)
{
return (string)_SanitizeIdentifier.Invoke(null, [input])!;
}

public static string SanitizeLabel(object? _, string input)
{
return (string)_SanitizeLabel.Invoke(null, [input])!;
}

#endif
}

public static TheoryData<string, string> SanitizeIdentifierTestCases() =>
Expand Down
2 changes: 1 addition & 1 deletion tests/PathBench.Test/PathBench.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand Down
Loading