diff --git a/NuGet.config b/NuGet.config index 1707938c61..03704957e8 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/src/Microsoft.AspNet.Routing/RouteData.cs b/src/Microsoft.AspNet.Routing/RouteData.cs index 4d734e3fb4..dbc4da9d6b 100644 --- a/src/Microsoft.AspNet.Routing/RouteData.cs +++ b/src/Microsoft.AspNet.Routing/RouteData.cs @@ -11,14 +11,16 @@ namespace Microsoft.AspNet.Routing /// public class RouteData { + private Dictionary _dataTokens; + private RouteValueDictionary _values; + /// /// Creates a new instance. /// public RouteData() { - DataTokens = new Dictionary(StringComparer.OrdinalIgnoreCase); + // Perf: Avoid allocating DataTokens and RouteValues unless needed. Routers = new List(); - Values = new RouteValueDictionary(); } /// @@ -32,24 +34,55 @@ namespace Microsoft.AspNet.Routing throw new ArgumentNullException(nameof(other)); } - DataTokens = new Dictionary(other.DataTokens, StringComparer.OrdinalIgnoreCase); Routers = new List(other.Routers); - Values = new RouteValueDictionary(other.Values); + + // Perf: Avoid allocating DataTokens and RouteValues unless we need to make a copy. + if (other._dataTokens != null) + { + _dataTokens = new Dictionary(other._dataTokens, StringComparer.OrdinalIgnoreCase); + } + + if (other._values != null) + { + _values = new RouteValueDictionary(other._values); + } } /// /// Gets the data tokens produced by routes on the current routing path. /// - public IDictionary DataTokens { get; private set; } + public IDictionary DataTokens + { + get + { + if (_dataTokens == null) + { + _dataTokens = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + return _dataTokens; + } + } /// /// Gets the list of instances on the current routing path. /// - public List Routers { get; private set; } + public List Routers { get; } /// /// Gets the set of values produced by routes on the current routing path. /// - public IDictionary Values { get; private set; } + public IDictionary Values + { + get + { + if (_values == null) + { + _values = new RouteValueDictionary(); + } + + return _values; + } + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs b/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs index 19f87ebe6a..0f8988ec1a 100644 --- a/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs +++ b/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs @@ -133,7 +133,14 @@ namespace Microsoft.AspNet.Routing.Template var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); - MergeValues(newRouteData.DataTokens, _dataTokens); + + // Perf: Avoid accessing data tokens if you don't need to write to it, these dictionaries are all + // created lazily. + if (_dataTokens.Count > 0) + { + MergeValues(newRouteData.DataTokens, _dataTokens); + } + newRouteData.Routers.Add(_target); MergeValues(newRouteData.Values, values);