Skip to content

Commit 56982e5

Browse files
Merge pull request #679 from rolfbjarne/speedier-getdecls
Improve performance when fetching Decls.
2 parents e960202 + 12909e5 commit 56982e5

File tree

4 files changed

+54
-37
lines changed

4 files changed

+54
-37
lines changed

sources/ClangSharp/Cursors/Decls/Decl.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ private protected Decl(CXCursor handle, CXCursorKind expectedCursorKind, CX_Decl
3535
_attrs = LazyList.Create<Attr>(Handle.NumAttrs, (i) => TranslationUnit.GetOrCreate<Attr>(Handle.GetAttr(unchecked((uint)i))));
3636
_body = new ValueLazy<Stmt?>(() => !Handle.Body.IsNull ? TranslationUnit.GetOrCreate<Stmt>(Handle.Body) : null);
3737
_canonicalDecl = new ValueLazy<Decl>(() => TranslationUnit.GetOrCreate<Decl>(Handle.CanonicalCursor));
38-
_decls = LazyList.Create<Decl>(Handle.NumDecls, (i) => TranslationUnit.GetOrCreate<Decl>(Handle.GetDecl(unchecked((uint)i))));
38+
_decls = LazyList.Create<Decl>(Handle.NumDecls, (i, previousDecl) => {
39+
if (previousDecl is null)
40+
{
41+
return TranslationUnit.GetOrCreate<Decl>(Handle.GetDecl(unchecked((uint)i)));
42+
}
43+
else
44+
{
45+
return previousDecl.NextDeclInContext;
46+
}
47+
});
3948
_describedTemplate = new ValueLazy<TemplateDecl?>(() => {
4049
var describedTemplate = Handle.DescribedTemplate;
4150
return describedTemplate.IsNull ? null : TranslationUnit.GetOrCreate<TemplateDecl>(describedTemplate);

sources/ClangSharp/LazyList.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ internal static class LazyList
1717
return new LazyList<T>(count, valueFactory);
1818
}
1919

20+
public static LazyList<T> Create<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>(int count, Func<int, T?, T> valueFactory)
21+
where T : class
22+
{
23+
if (count <= 0)
24+
{
25+
return LazyList<T>.Empty;
26+
}
27+
return new LazyList<T>(count, valueFactory);
28+
}
29+
2030
public static LazyList<T, TBase> Create<T, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TBase>(LazyList<TBase> list, int skip = -1, int take = -1)
2131
where T : class, TBase
2232
where TBase : class

sources/ClangSharp/LazyList`1.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,23 @@ internal sealed class LazyList<[DynamicallyAccessedMembers(DynamicallyAccessedMe
1111
where T : class
1212
{
1313
internal readonly T[] _items;
14-
internal readonly Func<int, T> _valueFactory;
14+
internal readonly Func<int, T>? _valueFactory;
15+
internal readonly Func<int, T?, T>? _valueFactoryWithPreviousValue;
1516

1617
public static readonly LazyList<T> Empty = new LazyList<T>(0, _ => null!);
1718

1819
public LazyList(int count, Func<int, T> valueFactory)
1920
{
2021
_items = (count <= 0) ? [] : new T[count];
2122
_valueFactory = valueFactory;
23+
_valueFactoryWithPreviousValue = null;
24+
}
25+
26+
public LazyList(int count, Func<int, T?, T> valueFactoryWithPreviousValue)
27+
{
28+
_items = (count <= 0) ? [] : new T[count];
29+
_valueFactory = null;
30+
_valueFactoryWithPreviousValue = valueFactoryWithPreviousValue;
2231
}
2332

2433
public T this[int index]
@@ -30,7 +39,14 @@ public T this[int index]
3039

3140
if (item is null)
3241
{
33-
item = _valueFactory(index);
42+
if (_valueFactoryWithPreviousValue is not null)
43+
{
44+
item = _valueFactoryWithPreviousValue(index, index == 0 ? null : _items[index - 1]);
45+
}
46+
else
47+
{
48+
item = _valueFactory!.Invoke(index);
49+
}
3450
items[index] = item;
3551
}
3652

@@ -56,14 +72,7 @@ public void CopyTo(T[] array, int arrayIndex)
5672

5773
for (var i = 0; i < items.Length; i++)
5874
{
59-
var currentItem = items[i];
60-
61-
if (currentItem is null)
62-
{
63-
currentItem = _valueFactory(i);
64-
items[i] = currentItem;
65-
}
66-
75+
var currentItem = this[i];
6776
array[arrayIndex + i] = currentItem;
6877
}
6978
}
@@ -76,14 +85,7 @@ public int IndexOf(T item)
7685

7786
for (var i = 0; i < items.Length; i++)
7887
{
79-
var currentItem = items[i];
80-
81-
if (currentItem is null)
82-
{
83-
currentItem = _valueFactory(i);
84-
items[i] = currentItem;
85-
}
86-
88+
var currentItem = this[i];
8789
if (EqualityComparer<T>.Default.Equals(currentItem, item))
8890
{
8991
return i;

sources/ClangSharp/LazyList`2.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ internal sealed class LazyList<T, [DynamicallyAccessedMembers(DynamicallyAccesse
1212
where TBase : class
1313
{
1414
internal readonly TBase[] _items;
15-
internal readonly Func<int, TBase> _valueFactory;
15+
internal readonly Func<int, TBase>? _valueFactory;
16+
internal readonly Func<int, TBase?, TBase>? _valueFactoryWithPreviousValue;
1617

1718
private readonly int _start;
1819
private readonly int _count;
@@ -24,6 +25,7 @@ public LazyList(LazyList<TBase> list, int skip = -1, int take = -1)
2425

2526
_items = list._items;
2627
_valueFactory = list._valueFactory;
28+
_valueFactoryWithPreviousValue = list._valueFactoryWithPreviousValue;
2729

2830
_start = skip;
2931
_count = take;
@@ -38,7 +40,15 @@ public T this[int index]
3840

3941
if (item is null)
4042
{
41-
item = _valueFactory(index + _start);
43+
var idx = index + _start;
44+
if (_valueFactoryWithPreviousValue is not null)
45+
{
46+
item = _valueFactoryWithPreviousValue(idx, idx == 0 ? null : _items[idx - 1]);
47+
}
48+
else
49+
{
50+
item = _valueFactory!.Invoke(idx);
51+
}
4252
items[index] = item;
4353
}
4454

@@ -64,14 +74,7 @@ public void CopyTo(T[] array, int arrayIndex)
6474

6575
for (var i = 0; i < _count; i++)
6676
{
67-
var currentItem = items[i];
68-
69-
if (currentItem is null)
70-
{
71-
currentItem = _valueFactory(i + _start);
72-
items[i] = currentItem;
73-
}
74-
77+
var currentItem = this[i];
7578
array[arrayIndex + i] = (T)currentItem;
7679
}
7780
}
@@ -84,14 +87,7 @@ public int IndexOf(T item)
8487

8588
for (var i = 0; i < items.Length; i++)
8689
{
87-
var currentItem = items[i];
88-
89-
if (currentItem is null)
90-
{
91-
currentItem = _valueFactory(i + _start);
92-
items[i] = currentItem;
93-
}
94-
90+
var currentItem = this[i];
9591
if (EqualityComparer<T>.Default.Equals((T)currentItem, item))
9692
{
9793
return i;

0 commit comments

Comments
 (0)