Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vectorize Convert.ToBase64String #71795

Merged
merged 17 commits into from
Jul 10, 2022
Merged

Vectorize Convert.ToBase64String #71795

merged 17 commits into from
Jul 10, 2022

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Jul 8, 2022

Use Utf8's version which is already vectorized for both x86 and arm and covert it to UTF16. Up to 3.5x faster for large inputs.

Benchmarks:

public IEnumerable<byte[]> TestData()
{
    int[] lengths = { 65, 100, 1000, 4096 };
    foreach (var length in lengths)
        yield return Enumerable.Range(0, length).Select(i => (byte)i).ToArray();
}

[Benchmark]
[ArgumentsSource(nameof(TestData))]
public string ToBase64String(byte[] data) => Convert.ToBase64String(data);
|         Method |        Job |                   Toolchain |       data |        Mean |
|--------------- |----------- |---------------------------- |----------- |------------:|
| ToBase64String | Job-OMUPEN |      \Core_Root\corerun.exe |   Byte[65] |    65.19 ns |
| ToBase64String | Job-BBSFOG | \Core_Root_base\corerun.exe |   Byte[65] |    82.50 ns |

| ToBase64String | Job-OMUPEN |      \Core_Root\corerun.exe |  Byte[100] |    66.05 ns |
| ToBase64String | Job-BBSFOG | \Core_Root_base\corerun.exe |  Byte[100] |   121.54 ns |

| ToBase64String | Job-OMUPEN |      \Core_Root\corerun.exe | Byte[1000] |   398.56 ns |
| ToBase64String | Job-BBSFOG | \Core_Root_base\corerun.exe | Byte[1000] | 1,124.47 ns |

| ToBase64String | Job-OMUPEN |      \Core_Root\corerun.exe | Byte[4096] | 1,320.25 ns |
| ToBase64String | Job-BBSFOG | \Core_Root_base\corerun.exe | Byte[4096] | 4,507.10 ns |

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

@ghost ghost assigned EgorBo Jul 8, 2022
Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@stephentoub
Copy link
Member

A bunch of related test failures

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done that before :-)

@a74nh
Copy link
Contributor

a74nh commented Jul 12, 2022

Is there anything still to do for Arm64 on this? I looked at the patch and couldn't see anything X64 specific in it.

@EgorBo
Copy link
Member Author

EgorBo commented Jul 12, 2022

Is there anything still to do for Arm64 on this? I looked at the patch and couldn't see anything X64 specific in it.

Initially, I submitted an x64-only implementation but then switched to the utf8 one + extension to utf16, so don't worry 🙂

@EgorBo EgorBo deleted the base64-u16 branch July 12, 2022 09:25
@a74nh
Copy link
Contributor

a74nh commented Jul 12, 2022

Initially, I submitted an x64-only implementation but then switched to the utf8 one + extension to utf16, so don't worry 🙂

Ok, that's fine then.

@EgorBo
Copy link
Member Author

EgorBo commented Jul 12, 2022

Improvements on Linux-x64 dotnet/perf-autofiling-issues#6731
Improvements on Alpine-x64 dotnet/perf-autofiling-issues#6743

@@ -2336,7 +2339,30 @@ public static string ToBase64String(ReadOnlySpan<byte> bytes, Base64FormattingOp
}

bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
string result = string.FastAllocateString(ToBase64_CalculateAndValidateOutputLength(bytes.Length, insertLineBreaks));
int outputLength = ToBase64_CalculateAndValidateOutputLength(bytes.Length, insertLineBreaks);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EgorBo, do we need something similar to this change for Convert.ToBase64CharArray?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephentoub makes sense!

@dakersnar
Copy link
Contributor

x86 improvements dotnet/perf-autofiling-issues#6952

@EgorBo
Copy link
Member Author

EgorBo commented Aug 18, 2022

@DrewScoggins
Copy link
Member

ubuntu x64 improvements: dotnet/perf-autofiling-issues#6960

@ghost ghost locked as resolved and limited conversation to collaborators Sep 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants