Skip to content

Commit

Permalink
Optimize StringHelper.Concat
Browse files Browse the repository at this point in the history
  • Loading branch information
mikernet committed Dec 8, 2023
1 parent ef10093 commit 70ef39a
Showing 1 changed file with 37 additions and 30 deletions.
67 changes: 37 additions & 30 deletions Source/Singulink.IO.FileSystem/Utilities/StringHelper.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
using System;

namespace Singulink.IO.Utilities
namespace Singulink.IO.Utilities;

#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type

internal static class StringHelper
{
internal static class StringHelper
public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2)
{
public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2)
{
fixed (char* p1 = s1)
fixed (char* p2 = s2) {
var data = (p1: (IntPtr)p1, p2: (IntPtr)p2, length1: s1.Length, length2: s2.Length);

return string.Create(s1.Length + s2.Length, data, (span, data) =>
{
new ReadOnlySpan<char>((char*)data.p1, data.length1).CopyTo(span);
new ReadOnlySpan<char>((char*)data.p2, data.length2).CopyTo(span.Slice(data.length1));
});
}
}

public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2, ReadOnlySpan<char> s3)
{
fixed (char* p1 = s1)
fixed (char* p2 = s2)
fixed (char* p3 = s3) {
var data = (p1: (IntPtr)p1, p2: (IntPtr)p2, p3: (IntPtr)p3, length1: s1.Length, length2: s2.Length, length3: s3.Length);

return string.Create(s1.Length + s2.Length + s3.Length, data, (span, data) => {
new ReadOnlySpan<char>((char*)data.p1, data.length1).CopyTo(span);
new ReadOnlySpan<char>((char*)data.p2, data.length2).CopyTo(span = span.Slice(data.length1));
new ReadOnlySpan<char>((char*)data.p3, data.length3).CopyTo(span.Slice(data.length2));
});
}
}
var p1 = &s1;
var p2 = &s2;

var data = (p1: (nint)p1, p2: (nint)p2);

return string.Create(s1.Length + s2.Length, data, (span, data) => {
var s1 = *(ReadOnlySpan<char>*)data.p1;
var s2 = *(ReadOnlySpan<char>*)data.p2;
s1.CopyTo(span);
s2.CopyTo(span.Slice(s1.Length));
});
}

public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2, ReadOnlySpan<char> s3)
{
var p1 = &s1;
var p2 = &s2;
var p3 = &s3;

var data = (p1: (nint)p1, p2: (nint)p2, p3: (nint)p3);

return string.Create(s1.Length + s2.Length + s3.Length, data, (span, data) => {
var s1 = *(ReadOnlySpan<char>*)data.p1;
var s2 = *(ReadOnlySpan<char>*)data.p2;
var s3 = *(ReadOnlySpan<char>*)data.p3;
s1.CopyTo(span);
s2.CopyTo(span = span.Slice(s1.Length));
s3.CopyTo(span.Slice(s2.Length));
});
}
}

0 comments on commit 70ef39a

Please sign in to comment.