Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2561 from justinvp/httpmethod
Browse files Browse the repository at this point in the history
Optimize HttpMethod.GetHashCode()
  • Loading branch information
davidsh committed Aug 24, 2015
2 parents 28aaab7 + a75896b commit e296c69
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 13 deletions.
37 changes: 29 additions & 8 deletions src/System.Net.Http/src/System/Net/Http/HttpMethod.cs
@@ -1,17 +1,14 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.Contracts;
using System.Diagnostics;

namespace System.Net.Http
{
public class HttpMethod : IEquatable<HttpMethod>
{
private string _method;
private readonly string _method;
private int _hashcode;

private static readonly HttpMethod s_getMethod = new HttpMethod("GET");
private static readonly HttpMethod s_putMethod = new HttpMethod("PUT");
Expand All @@ -21,7 +18,7 @@ public class HttpMethod : IEquatable<HttpMethod>
private static readonly HttpMethod s_optionsMethod = new HttpMethod("OPTIONS");
private static readonly HttpMethod s_traceMethod = new HttpMethod("TRACE");

// Don't expose CONNECT as static property, since it's used by the transport to connect to a proxy.
// Don't expose CONNECT as static property, since it's used by the transport to connect to a proxy.
// CONNECT is not used by users directly.

public static HttpMethod Get
Expand Down Expand Up @@ -106,7 +103,17 @@ public override bool Equals(object obj)

public override int GetHashCode()
{
return _method.ToUpperInvariant().GetHashCode();
if (_hashcode == 0)
{
// If _method is already uppercase, _method.GetHashCode() can be
// used instead of _method.ToUpperInvariant().GetHashCode(),
// avoiding the unnecessary extra string allocation.
_hashcode = IsUpperAscii(_method) ?
_method.GetHashCode() :
_method.ToUpperInvariant().GetHashCode();
}

return _hashcode;
}

public override string ToString()
Expand All @@ -132,5 +139,19 @@ public override string ToString()
{
return !(left == right);
}

private static bool IsUpperAscii(string value)
{
for (int i = 0; i < value.Length; i++)
{
char c = value[i];
if (!(c >= 'A' && c <= 'Z'))
{
return false;
}
}

return true;
}
}
}
35 changes: 30 additions & 5 deletions src/System.Net.Http/tests/FunctionalTests/HttpMethodTest.cs
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;

Expand All @@ -11,6 +12,19 @@ namespace System.Net.Http.Tests
{
public class HttpMethodTest
{
private static readonly object[][] s_staticHttpMethods =
{
new object[] { HttpMethod.Get },
new object[] { HttpMethod.Put },
new object[] { HttpMethod.Post },
new object[] { HttpMethod.Delete },
new object[] { HttpMethod.Head },
new object[] { HttpMethod.Options },
new object[] { HttpMethod.Trace }
};

public static IEnumerable<object[]> StaticHttpMethods { get { return s_staticHttpMethods; } }

[Fact]
public void StaticProperties_VerifyValues_PropertyNameMatchesHttpMethodName()
{
Expand Down Expand Up @@ -80,12 +94,23 @@ public void Equals_NullComparand_ReturnsFalse()
Assert.False(HttpMethod.Trace == null);
}

[Fact]
public void GetHashCode_UseCustomStringMethod_SameAsStringHashCode()
[Theory]
[InlineData("GET")]
[InlineData("get")]
[InlineData("Get")]
[InlineData("CUSTOM")]
[InlineData("cUsToM")]
public void GetHashCode_CustomStringMethod_SameAsStringToUpperInvariantHashCode(string input)
{
string custom = "CUSTOM";
HttpMethod method = new HttpMethod(custom);
Assert.Equal(custom.GetHashCode(), method.GetHashCode());
HttpMethod method = new HttpMethod(input);
Assert.Equal(input.ToUpperInvariant().GetHashCode(), method.GetHashCode());
}

[Theory]
[MemberData("StaticHttpMethods")]
public void GetHashCode_StaticMethods_SameAsStringToUpperInvariantHashCode(HttpMethod method)
{
Assert.Equal(method.ToString().ToUpperInvariant().GetHashCode(), method.GetHashCode());
}

[Fact]
Expand Down

0 comments on commit e296c69

Please sign in to comment.