Skip to content

Commit 0ce83a3

Browse files
committed
No copies of collection on attributes extraction
The caller does final .ToArray(), no need to copy arrays to extra List, out returning actual count count will help to not have IEnumerable<> enumeration to get result array size
1 parent 84e4ba4 commit 0ce83a3

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

Orm/Xtensive.Orm/Reflection/AttributeHelper.cs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2008-2021 Xtensive LLC.
1+
// Copyright (C) 2008-2022 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alex Yakunin
@@ -11,6 +11,7 @@
1111
using System.Reflection;
1212
using AttributesKey = System.ValueTuple<System.Reflection.MemberInfo, System.Type, Xtensive.Reflection.AttributeSearchOptions>;
1313
using PerAttributeKey = System.ValueTuple<System.Reflection.MemberInfo, Xtensive.Reflection.AttributeSearchOptions>;
14+
using Xtensive.Core;
1415

1516
namespace Xtensive.Reflection
1617
{
@@ -71,7 +72,7 @@ public static TAttribute GetAttribute<TAttribute>(this MemberInfo member, Attrib
7172
private static IReadOnlyList<Attribute> GetAttributes(MemberInfo member, Type attributeType, AttributeSearchOptions options) =>
7273
attributesByMemberInfoAndSearchOptions.GetOrAdd(
7374
new AttributesKey(member, attributeType, options),
74-
t => ExtractAttributes(t).ToArray()
75+
t => ExtractAttributes(t, out var count).ToArray(count)
7576
);
7677

7778
private static Attribute[] GetAttributes(this MemberInfo member, Type attributeType)
@@ -84,30 +85,48 @@ private static Attribute[] GetAttributes(this MemberInfo member, Type attributeT
8485
return attrs;
8586
}
8687

87-
private static IEnumerable<Attribute> ExtractAttributes((MemberInfo member, Type attributeType, AttributeSearchOptions options) t) {
88+
private static IEnumerable<Attribute> ExtractAttributes((MemberInfo member, Type attributeType, AttributeSearchOptions options) t, out int count)
89+
{
8890
(var member, var attributeType, var options) = t;
8991

90-
var attributes = member.GetCustomAttributes(attributeType, false).Cast<Attribute>().ToList();
91-
if (options == AttributeSearchOptions.InheritNone)
92-
return attributes;
93-
if (attributes.Count == 0) {
92+
var customAttributesRaw = member.GetCustomAttributes(attributeType, false);
93+
count = customAttributesRaw.Length;
94+
95+
if (options == AttributeSearchOptions.InheritNone) {
96+
return (customAttributesRaw.Length == 0)
97+
? Array.Empty<Attribute>()
98+
: customAttributesRaw.Cast<Attribute>();// no new collection
99+
}
100+
101+
IEnumerable<Attribute> attributes;
102+
if (customAttributesRaw.Length == 0) {
103+
attributes = Enumerable.Empty<Attribute>();
94104
if ((options & AttributeSearchOptions.InheritFromPropertyOrEvent) != 0
95105
&& member is MethodInfo m
96106
&& ((MemberInfo) m.GetProperty() ?? m.GetEvent()) is MemberInfo poe) {
97-
attributes = poe.GetAttributes(attributeType).ToList();
107+
var poeAttributes = poe.GetAttributes(attributeType);
108+
count = poeAttributes.Length;
109+
attributes = poeAttributes;
98110
}
99111
if ((options & AttributeSearchOptions.InheritFromBase) != 0
100112
&& (options & AttributeSearchOptions.InheritRecursively) == 0
101113
&& member.GetBaseMember() is MemberInfo bm) {
102-
attributes.AddRange(GetAttributes(bm, attributeType, options));
114+
var inheritedAttributes = GetAttributes(bm, attributeType, options);
115+
count += inheritedAttributes.Count;
116+
attributes = attributes.Concat(inheritedAttributes);
103117
return attributes;
104118
}
105119
}
120+
else {
121+
attributes = customAttributesRaw.Cast<Attribute>();
122+
}
106123

107124
if ((options & AttributeSearchOptions.InheritFromAllBase) == AttributeSearchOptions.InheritFromAllBase
108125
&& member.DeclaringType != WellKnownTypes.Object
109126
&& member.GetBaseMember() is MemberInfo bm2) {
110-
attributes.AddRange(GetAttributes(bm2, attributeType, options));
127+
var inheritedAttributes = GetAttributes(bm2, attributeType, options);
128+
count += inheritedAttributes.Count;
129+
attributes = attributes.Concat(inheritedAttributes);
111130
}
112131

113132
return attributes;

0 commit comments

Comments
 (0)