Skip to content

Commit

Permalink
Improve the performance of RollingWindow.GetEnumerator (#8444)
Browse files Browse the repository at this point in the history
* improve the performance of RollingWindow.GetEnumerator

Closes #8443

* address review comments
  • Loading branch information
starteleport authored Dec 5, 2024
1 parent 8e5893b commit 22e0491
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
25 changes: 17 additions & 8 deletions Common/Indicators/RollingWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;

namespace QuantConnect.Indicators
Expand Down Expand Up @@ -174,7 +175,7 @@ public T this [int i]
return default;
}

return _list[(_list.Count + _tail - i - 1) % _list.Count];
return _list[GetListIndex(i, _list.Count, _tail)];
}
finally
{
Expand Down Expand Up @@ -206,7 +207,7 @@ public T this [int i]
}
}

_list[(_list.Count + _tail - i - 1) % _list.Count] = value;
_list[GetListIndex(i, _list.Count, _tail)] = value;
}
finally
{
Expand Down Expand Up @@ -244,18 +245,20 @@ public bool IsReady
/// <filterpriority>1</filterpriority>
public IEnumerator<T> GetEnumerator()
{
// we make a copy on purpose so the enumerator isn't tied
// to a mutable object, well it is still mutable but out of scope
var temp = new List<T>(_list.Count);
try
{
_listLock.EnterReadLock();

for (int i = 0; i < _list.Count; i++)
// we make a copy on purpose so the enumerator isn't tied
// to a mutable object, well it is still mutable but out of scope
var count = _list.Count;
var temp = new T[count];
for (int i = 0; i < count; i++)
{
temp.Add(this[i]);
temp[i] = _list[GetListIndex(i, count, _tail)];
}
return temp.GetEnumerator();

return ((IEnumerable<T>) temp).GetEnumerator();
}
finally
{
Expand Down Expand Up @@ -325,6 +328,12 @@ public void Reset()
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetListIndex(int index, int listCount, int tail)
{
return (listCount + tail - index - 1) % listCount;
}

private void Resize(int size)
{
try
Expand Down
6 changes: 6 additions & 0 deletions Tests/Indicators/RollingWindowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ public void EnumeratesAsExpected()
Assert.AreEqual(2, inOrder[0]);
Assert.AreEqual(1, inOrder[1]);
Assert.AreEqual(0, inOrder[2]);

window.Add(3);
var inOrder2 = window.ToList();
Assert.AreEqual(3, inOrder2[0]);
Assert.AreEqual(2, inOrder2[1]);
Assert.AreEqual(1, inOrder2[2]);
}

[Test]
Expand Down

0 comments on commit 22e0491

Please sign in to comment.