Improve fast path of ManagedFileSystem.GetValidFilename

|                      Method |          Data |        Mean |     Error |    StdDev |      Median |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------------------------- |-------------- |------------:|----------:|----------:|------------:|-------:|------:|------:|----------:|
|       GetValidFilenameBench |    AC/DCKD/A |    52.29 ns |  0.537 ns |  0.448 ns |    52.35 ns | 0.0255 |     - |     - |      80 B |
|    GetValidFilenameOldBench |    AC/DCKD/A |    86.68 ns |  1.205 ns |  1.127 ns |    86.33 ns | 0.0587 |     - |     - |     184 B |
|    GetValidFilenameWinBench |    AC/DCKD/A |   448.55 ns |  1.228 ns |  1.088 ns |   448.33 ns | 0.0505 |     - |     - |     160 B |
| GetValidFilenameOldWinBench |    AC/DCKD/A |   865.21 ns |  5.734 ns |  5.083 ns |   866.60 ns | 0.0839 |     - |     - |     264 B |
|       GetValidFilenameBench | ValidFileName |    16.00 ns |  0.234 ns |  0.207 ns |    16.02 ns | 0.0102 |     - |     - |      32 B |
|    GetValidFilenameOldBench | ValidFileName |   100.66 ns |  1.255 ns |  1.174 ns |   101.21 ns | 0.0587 |     - |     - |     184 B |
|    GetValidFilenameWinBench | ValidFileName |   116.60 ns |  1.624 ns |  1.519 ns |   116.88 ns | 0.0356 |     - |     - |     112 B |
| GetValidFilenameOldWinBench | ValidFileName | 1,052.66 ns | 18.077 ns | 33.056 ns | 1,037.25 ns | 0.0839 |     - |     - |     264 B |
pull/5891/head
Bond_009 4 years ago
parent 81209258ab
commit 33327aa1a9

@ -302,28 +302,27 @@ namespace Emby.Server.Implementations.IO
/// <exception cref="ArgumentNullException">The filename is null.</exception> /// <exception cref="ArgumentNullException">The filename is null.</exception>
public string GetValidFilename(string filename) public string GetValidFilename(string filename)
{ {
return string.Create(
filename.Length,
filename,
(chars, state) =>
{
state.AsSpan().CopyTo(chars);
var invalid = Path.GetInvalidFileNameChars(); var invalid = Path.GetInvalidFileNameChars();
var first = filename.IndexOfAny(invalid);
var first = state.AsSpan().IndexOfAny(invalid);
if (first == -1) if (first == -1)
{ {
// Fast path for clean strings // Fast path for clean strings
return; return filename;
} }
chars[first++] = ' '; return string.Create(
filename.Length,
(filename, invalid, first),
(chars, state) =>
{
state.filename.AsSpan().CopyTo(chars);
chars[state.first++] = ' ';
var len = chars.Length; var len = chars.Length;
foreach (var c in invalid) foreach (var c in state.invalid)
{ {
for (int i = first; i < len; i++) for (int i = state.first; i < len; i++)
{ {
if (chars[i] == c) if (chars[i] == c)
{ {

Loading…
Cancel
Save