diff --git a/src/System.Net.Primitives/src/System/Net/IPAddressParser.cs b/src/System.Net.Primitives/src/System/Net/IPAddressParser.cs index 648987999a24..825aa865666b 100644 --- a/src/System.Net.Primitives/src/System/Net/IPAddressParser.cs +++ b/src/System.Net.Primitives/src/System/Net/IPAddressParser.cs @@ -180,27 +180,29 @@ private static void FormatIPv4AddressNumber(int number, Span addressString public static unsafe bool Ipv4StringToAddress(ReadOnlySpan ipSpan, out long address) { int end = ipSpan.Length; + long tmpAddr; + fixed (char* ipStringPtr = &ipSpan.DangerousGetPinnableReference()) { - long tmpAddr = IPv4AddressHelper.ParseNonCanonical(ipStringPtr, 0, ref end, notImplicitFile: true); + tmpAddr = IPv4AddressHelper.ParseNonCanonical(ipStringPtr, 0, ref end, notImplicitFile: true); + } - if (tmpAddr != IPv4AddressHelper.Invalid && end == ipSpan.Length) - { - // IPv4AddressHelper.ParseNonCanonical returns the bytes in the inverse order. - // Reverse them and return success. - address = - ((0xFF000000 & tmpAddr) >> 24) | - ((0x00FF0000 & tmpAddr) >> 8) | - ((0x0000FF00 & tmpAddr) << 8) | - ((0x000000FF & tmpAddr) << 24); - return true; - } - else - { - // Failed to parse the address. - address = 0; - return false; - } + if (tmpAddr != IPv4AddressHelper.Invalid && end == ipSpan.Length) + { + // IPv4AddressHelper.ParseNonCanonical returns the bytes in the inverse order. + // Reverse them and return success. + address = + ((0xFF000000 & tmpAddr) >> 24) | + ((0x00FF0000 & tmpAddr) >> 8) | + ((0x0000FF00 & tmpAddr) << 8) | + ((0x000000FF & tmpAddr) << 24); + return true; + } + else + { + // Failed to parse the address. + address = 0; + return false; } } diff --git a/src/System.Net.Primitives/tests/PerformanceTests/IPAddressPerformanceTests.cs b/src/System.Net.Primitives/tests/PerformanceTests/IPAddressPerformanceTests.cs index 75456183c52b..babc47ab0946 100644 --- a/src/System.Net.Primitives/tests/PerformanceTests/IPAddressPerformanceTests.cs +++ b/src/System.Net.Primitives/tests/PerformanceTests/IPAddressPerformanceTests.cs @@ -28,7 +28,13 @@ public static void TryWriteBytes(byte[] address) { using (iteration.StartMeasurement()) { - ip.TryWriteBytes(bytesSpan, out bytesWritten); + for (int i = 0; i < 10000; ++i) + { + ip.TryWriteBytes(bytesSpan, out bytesWritten); ip.TryWriteBytes(bytesSpan, out bytesWritten); + ip.TryWriteBytes(bytesSpan, out bytesWritten); ip.TryWriteBytes(bytesSpan, out bytesWritten); + ip.TryWriteBytes(bytesSpan, out bytesWritten); ip.TryWriteBytes(bytesSpan, out bytesWritten); + ip.TryWriteBytes(bytesSpan, out bytesWritten); ip.TryWriteBytes(bytesSpan, out bytesWritten); + } } } } @@ -39,11 +45,18 @@ public static void TryWriteBytes(byte[] address) public static void GetAddressBytes(byte[] address) { var ip = new IPAddress(address); + byte[] bytes; + foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { - var bytes = ip.GetAddressBytes(); + for (int i = 0; i < 10000; ++i) + { + bytes = ip.GetAddressBytes(); bytes = ip.GetAddressBytes(); + bytes = ip.GetAddressBytes(); bytes = ip.GetAddressBytes(); + bytes = ip.GetAddressBytes(); bytes = ip.GetAddressBytes(); + } } } } @@ -53,11 +66,18 @@ public static void GetAddressBytes(byte[] address) [MemberData(nameof(TestAddresses))] public static void Ctor_Bytes(byte[] address) { + IPAddress ip; foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { - var ip = new IPAddress(address); + for (int i = 0; i < 10000; ++i) + { + ip = new IPAddress(address); ip = new IPAddress(address); + ip = new IPAddress(address); ip = new IPAddress(address); + ip = new IPAddress(address); ip = new IPAddress(address); + ip = new IPAddress(address); ip = new IPAddress(address); + } } } } @@ -68,11 +88,18 @@ public static void Ctor_Bytes(byte[] address) public static void Ctor_Span(byte[] address) { var span = new ReadOnlySpan(address); + IPAddress ip; foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { - var ip = new IPAddress(span); + for (int i = 0; i < 10000; ++i) + { + ip = new IPAddress(span); ip = new IPAddress(span); + ip = new IPAddress(span); ip = new IPAddress(span); + ip = new IPAddress(span); ip = new IPAddress(span); + ip = new IPAddress(span); ip = new IPAddress(span); + } } } } @@ -85,6 +112,7 @@ public static void TryFormat(byte[] address) const int INET6_ADDRSTRLEN = 65; var buffer = new char[INET6_ADDRSTRLEN]; var result = new Span(buffer); + int charsWritten; var ip = new IPAddress(address); @@ -92,7 +120,10 @@ public static void TryFormat(byte[] address) { using (iteration.StartMeasurement()) { - ip.TryFormat(result, out int charsWritten); + for (int i = 0; i < 10000; ++i) + { + ip.TryFormat(result, out charsWritten); + } } } } @@ -104,11 +135,20 @@ public static void ToString(byte[] address) { var ip = new IPAddress(address); + string result; foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { - var result = ip.ToString(); + for (int i = 0; i < 10000; ++i) + { + result = ip.ToString(); result = ip.ToString(); + result = ip.ToString(); result = ip.ToString(); + result = ip.ToString(); result = ip.ToString(); + result = ip.ToString(); result = ip.ToString(); + result = ip.ToString(); result = ip.ToString(); + result = ip.ToString(); result = ip.ToString(); + } } } }