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

Add System.Memory reference #31162

Merged
merged 4 commits into from
Nov 15, 2018
Merged

Conversation

agocke
Copy link
Member

@agocke agocke commented Nov 14, 2018

Allows us to replace some unsafe code with Span. I anticipate more complex
uses in the future.

Here are the benchmarks.

Before

BenchmarkDotNet=v0.11.1, OS=Windows 10.0.17134.345 (1803/April2018Update/Redstone4)
Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.2.200-preview-009431
  [Host] : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
  Core   : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT

Job=Core  Runtime=Core  Server=True

                Method |      Mean |     Error |    StdDev |    Median |     Gen 0 | Allocated |
---------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
               Parsing |  96.86 ms |  2.568 ms |  7.571 ms |  96.89 ms |         - |   4.25 MB |
 CompileMethodsAndEmit | 688.64 ms | 13.659 ms | 38.971 ms | 681.50 ms | 1000.0000 |  43.97 MB |
     SerializeMetadata | 231.56 ms | 10.722 ms | 31.613 ms | 244.91 ms |         - |  18.06 MB |

After

BenchmarkDotNet=v0.11.1, OS=Windows 10.0.17134.345 (1803/April2018Update/Redstone4)
Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.2.200-preview-009431
  [Host] : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
  Core   : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT

Job=Core  Runtime=Core  Server=True

                Method |      Mean |     Error |    StdDev |    Median |     Gen 0 | Allocated |
---------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
               Parsing |  95.71 ms |  2.381 ms |  7.021 ms |  95.44 ms |         - |   3.59 MB |
 CompileMethodsAndEmit | 708.76 ms | 19.100 ms | 55.108 ms | 707.51 ms | 1000.0000 |  44.02 MB |
     SerializeMetadata | 199.04 ms |  8.754 ms | 24.834 ms | 191.37 ms |         - |  18.06 MB |

There does not appear to be any statistically significant difference.

@agocke agocke requested review from jaredpar and a team November 14, 2018 00:22
@agocke agocke requested a review from a team as a code owner November 14, 2018 00:22
/// <param name="isAscii">True if the sequence contains only characters in the ASCII range.</param>
/// <returns>The FNV-1a hash of <paramref name="data"/></returns>
internal static unsafe int GetFNVHashCode(byte* data, int length, out bool isAscii)
internal static int GetFNVHashCode(ReadOnlySpan<byte> data, out bool isAscii)
Copy link
Member

Choose a reason for hiding this comment

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

this makes me so happy :)

@agocke agocke changed the base branch from master to dev16.0-preview2 November 14, 2018 00:29
Also replaces some unsafe code with Span<T>.
return true;
}
internal static bool TextEquals(string array, ReadOnlySpan<char> text)
=> text.Equals(array.AsSpan(), StringComparison.Ordinal);
Copy link
Contributor

@Therzok Therzok Nov 14, 2018

Choose a reason for hiding this comment

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

I think this should be SequenceEquals.

Nevermind!

Therzok added a commit to mono/monodevelop that referenced this pull request Nov 14, 2018
Therzok added a commit to mono/monodevelop that referenced this pull request Nov 14, 2018
{
#if DEBUG
for (var i = 0; i < length; i++)
for (var i = 0; i < ascii.Length; i++)
{
Debug.Assert((ascii[i] & 0x80) == 0, "The byte* input to this method must be valid ASCII.");
Copy link
Member

Choose a reason for hiding this comment

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

byte* [](start = 58, length = 5)

This message is out-of-date

return true;
}
internal static bool TextEquals(string array, ReadOnlySpan<char> text)
=> text.Equals(array.AsSpan(), StringComparison.Ordinal);
Copy link
Member

@jcouv jcouv Nov 15, 2018

Choose a reason for hiding this comment

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

text.Equals [](start = 15, length = 11)

I didn't understand how this .Equals works.
ReadOnlySpan.Equals seems to throw an exception (source )

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

(Spans can't be boxed anyway, so that method couldn't be the target)

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

@@ -118,7 +118,7 @@ internal T FindItem(char[] chars, int start, int len, int hashCode)

if (text != null && localSlot.HashCode == hashCode)
{
if (StringTable.TextEquals(text, chars, start, len))
if (StringTable.TextEquals(text, chars.AsSpan(start, len)))
Copy link
Member

Choose a reason for hiding this comment

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

AsSpan [](start = 55, length = 6)

AsReadOnlySpan? (also below)

Copy link
Member Author

Choose a reason for hiding this comment

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

There's an implicit conversion, doesn't matter.

@jcouv
Copy link
Member

jcouv commented Nov 15, 2018

I assume the benchmarks in the description were for a previous iteration with a broader change.

<ExpectedDependency Include="System.Runtime.CompilerServices.Unsafe" DevEnvLib="lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll"/>
<ExpectedDependency Include="System.Text.Encoding.CodePages" DevEnvLib="lib/netstandard2.0/System.Text.Encoding.CodePages.dll"/>
<ExpectedDependency Include="System.Numerics.Vectors" DevEnvLib="lib/netstandard2.0/System.Numerics.Vectors.dll" />
Copy link
Member

Choose a reason for hiding this comment

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

System.Numerics.Vectors [](start = 33, length = 23)

Does this relate to System.Memory?

Copy link
Member Author

Choose a reason for hiding this comment

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

Dependent reference.

@@ -223,6 +223,8 @@ public class TestAnalyzer : DiagnosticAnalyzer

dir.CopyFile(typeof(System.Reflection.Metadata.MetadataReader).Assembly.Location);
dir.CopyFile(typeof(AppDomainUtils).Assembly.Location);
dir.CopyFile(typeof(Memory<byte>).Assembly.Location);
Copy link
Member

Choose a reason for hiding this comment

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

byte [](start = 39, length = 4)

nit: the byte is probably not needed: typeof(Memory<>) (here and in TestHelpers.cs)

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 3) with some clarifying questions

@jcouv jcouv self-assigned this Nov 15, 2018
@jcouv jcouv added this to the 16.0.P2 milestone Nov 15, 2018
@agocke agocke merged commit db3a9f3 into dotnet:dev16.0-preview2 Nov 15, 2018
@agocke agocke deleted the add-memory-ref branch November 15, 2018 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants