Skip to content

Commit

Permalink
feat: optimize RestMethodInfo, reduce dictionary allocations and li…
Browse files Browse the repository at this point in the history
…nq iterations (#1742)
  • Loading branch information
TimothyMakkison authored Jun 29, 2024
1 parent f5b1690 commit ea1cc52
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 93 deletions.
48 changes: 24 additions & 24 deletions Refit.Tests/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,8 +1062,8 @@ public void DynamicHeaderCollectionShouldWork()
Assert.Equal("1", fixture.Headers["Api-Version"]);

Assert.Equal(4, fixture.Headers.Count);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
}

[Theory]
Expand All @@ -1085,8 +1085,8 @@ public void DynamicHeaderCollectionShouldWorkWithBody(string interfaceMethodName
Assert.NotNull(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);

Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(2));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(2));
}

[Theory]
Expand All @@ -1110,8 +1110,8 @@ public void DynamicHeaderCollectionShouldWorkWithoutBody(string interfaceMethodN
Assert.Null(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);

Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
}

[Theory]
Expand Down Expand Up @@ -1141,8 +1141,8 @@ public void DynamicHeaderCollectionShouldWorkWithInferredBody(string interfaceMe
Assert.NotNull(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);

Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
Assert.Equal(2, fixture.BodyParameterInfo.Item3);
}

Expand All @@ -1168,8 +1168,8 @@ public void DynamicHeaderCollectionShouldWorkWithAuthorize(string interfaceMetho
Assert.Null(fixture.BodyParameterInfo);

Assert.NotNull(fixture.AuthorizeParameterInfo);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(2));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(2));
}

[Theory]
Expand All @@ -1195,8 +1195,8 @@ public void DynamicHeaderCollectionShouldWorkWithDynamicHeader(string interfaceM

Assert.Single(fixture.HeaderParameterMap);
Assert.Equal("Authorization", fixture.HeaderParameterMap[1]);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(2));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(2));

input = typeof(IRestMethodInfoTests);
fixture = new RestMethodInfoInternal(
Expand All @@ -1220,8 +1220,8 @@ public void DynamicHeaderCollectionShouldWorkWithDynamicHeader(string interfaceM

Assert.Single(fixture.HeaderParameterMap);
Assert.Equal("Authorization", fixture.HeaderParameterMap[2]);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
}

[Theory]
Expand Down Expand Up @@ -1253,8 +1253,8 @@ string interfaceMethodName

Assert.Single(fixture.HeaderParameterMap);
Assert.Equal("X-PathMember", fixture.HeaderParameterMap[0]);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
}

[Theory]
Expand All @@ -1274,8 +1274,8 @@ public void DynamicHeaderCollectionInMiddleOfParamsShouldWork(string interfaceMe
Assert.Null(fixture.BodyParameterInfo);

Assert.Equal("baz", fixture.QueryParameterMap[2]);
Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(1));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(1));
}

[Theory]
Expand Down Expand Up @@ -1321,8 +1321,8 @@ public void DynamicHeaderCollectionShouldWorkWithProperty(string interfaceMethod

Assert.Single(fixture.PropertyParameterMap);

Assert.Equal(1, fixture.HeaderCollectionParameterMap.Count);
Assert.True(fixture.HeaderCollectionParameterMap.Contains(0));
Assert.True(fixture.HasHeaderCollection);
Assert.True(fixture.HeaderCollectionAt(0));
}

[Theory]
Expand Down Expand Up @@ -1393,7 +1393,7 @@ public void DynamicRequestPropertyShouldWorkWithBody()
Assert.Empty(fixture.HeaderParameterMap);
Assert.NotNull(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);
Assert.Empty(fixture.HeaderCollectionParameterMap);
Assert.False(fixture.HasHeaderCollection);

Assert.Equal("SomeProperty", fixture.PropertyParameterMap[2]);
}
Expand All @@ -1420,7 +1420,7 @@ public void DynamicRequestPropertiesShouldWorkWithBody()
Assert.Empty(fixture.HeaderParameterMap);
Assert.NotNull(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);
Assert.Empty(fixture.HeaderCollectionParameterMap);
Assert.False(fixture.HasHeaderCollection);

Assert.Equal("SomeProperty", fixture.PropertyParameterMap[2]);
Assert.Equal("SomeOtherProperty", fixture.PropertyParameterMap[3]);
Expand Down Expand Up @@ -1449,7 +1449,7 @@ public void DynamicRequestPropertyShouldWorkWithoutBody(string interfaceMethodNa
Assert.Empty(fixture.HeaderParameterMap);
Assert.Null(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);
Assert.Empty(fixture.HeaderCollectionParameterMap);
Assert.False(fixture.HasHeaderCollection);

Assert.Equal("SomeProperty", fixture.PropertyParameterMap[1]);
}
Expand Down Expand Up @@ -1477,7 +1477,7 @@ public void DynamicRequestPropertyShouldWorkWithInferredBody(string interfaceMet
Assert.Empty(fixture.HeaderParameterMap);
Assert.NotNull(fixture.BodyParameterInfo);
Assert.Null(fixture.AuthorizeParameterInfo);
Assert.Empty(fixture.HeaderCollectionParameterMap);
Assert.False(fixture.HasHeaderCollection);

Assert.Equal("SomeProperty", fixture.PropertyParameterMap[1]);
Assert.Equal(2, fixture.BodyParameterInfo.Item3);
Expand Down
7 changes: 7 additions & 0 deletions Refit/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ internal static EnumerablePeek TryGetSingle<T>(this IEnumerable<T> enumerable, o
}
}

internal static class EmptyDictionary<TKey, TValue>
{
private static Dictionary<TKey, TValue> Value = new Dictionary<TKey, TValue>();

internal static Dictionary<TKey, TValue> Get() => Value;
}

internal enum EnumerablePeek
{
Empty,
Expand Down
16 changes: 8 additions & 8 deletions Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ bool paramsContainsCancellationToken
Uri.EscapeDataString(
settings.UrlParameterFormatter.Format(
s,
restMethod.ParameterInfoMap[i],
restMethod.ParameterInfoMap[i].ParameterType
restMethod.ParameterInfoArray[i],
restMethod.ParameterInfoArray[i].ParameterType
) ?? string.Empty
)
)
Expand All @@ -702,8 +702,8 @@ bool paramsContainsCancellationToken
replacement = Uri.EscapeDataString(
settings.UrlParameterFormatter.Format(
param,
restMethod.ParameterInfoMap[i],
restMethod.ParameterInfoMap[i].ParameterType
restMethod.ParameterInfoArray[i],
restMethod.ParameterInfoArray[i].ParameterType
) ?? string.Empty
);
}
Expand Down Expand Up @@ -738,7 +738,7 @@ bool paramsContainsCancellationToken
}

//if header collection, add to request headers
if (restMethod.HeaderCollectionParameterMap.Contains(i))
if (restMethod.HeaderCollectionAt(i))
{
if (param is IDictionary<string, string> headerCollection)
{
Expand Down Expand Up @@ -776,7 +776,7 @@ bool paramsContainsCancellationToken
// or if is an object bound to the path add any non-path bound properties to query string
// or if it's an object with a query attribute
var queryAttribute = restMethod
.ParameterInfoMap[i]
.ParameterInfoArray[i]
.GetCustomAttribute<QueryAttribute>();
if (
!restMethod.IsMultipart
Expand Down Expand Up @@ -897,7 +897,7 @@ void AddQueryParameters(RestMethodInfoInternal restMethod, QueryAttribute? query
queryParamsToAdd.AddRange(
ParseQueryParameter(
param,
restMethod.ParameterInfoMap[i],
restMethod.ParameterInfoArray[i],
restMethod.QueryParameterMap[i],
attr
)
Expand All @@ -913,7 +913,7 @@ void AddQueryParameters(RestMethodInfoInternal restMethod, QueryAttribute? query
queryParamsToAdd.AddRange(
ParseQueryParameter(
kvp.Value,
restMethod.ParameterInfoMap[i],
restMethod.ParameterInfoArray[i],
path,
attr
)
Expand Down
Loading

0 comments on commit ea1cc52

Please sign in to comment.