Dynamic Array - Performance

Questions about MultiCharts and user contributed studies.
javamarket
Posts: 55
Joined: 10 Jul 2014
Has thanked: 10 times
Been thanked: 18 times

Dynamic Array - Performance

Postby javamarket » 08 Aug 2014

I'm using the following to compare a variable number of consecutive bars with a dynamic array (abbreviated code). I tried to set a static array using the input variable but MC seems not to accept that.

Code: Select all

input: numBars(3);

vars: yesNo(false);

someArray[](0);

For ii = 1 to numBars begin
if H[ii-1] < H[ii] then someArray[ii] = 1 else someArray[ii] = 0;
end;

yesNo = Array_Sum(someArray,1,numBars) = numBars;
This should check for 3 (default) lower highs in a row.
I find the performance on this to be terrible.
Is there a better approach to compare consecutive values with MC?

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Dynamic Array - Performance

Postby JoshM » 09 Aug 2014

Is the performance still not good if you resize the array prior to calling `Array_Sum` or prior to looping through it? (See Array_SetMaxIndex).

javamarket
Posts: 55
Joined: 10 Jul 2014
Has thanked: 10 times
Been thanked: 18 times

Re: Dynamic Array - Performance

Postby javamarket » 09 Aug 2014

Is the performance still not good if you resize the array prior to calling `Array_Sum` or prior to looping through it? (See Array_SetMaxIndex).
Thanks Josh,

I do resize the array prior to calling sum, I neglected to write it above when I simplified the code. It actually looks like ...

Code: Select all

array: someArray[](0);
Array_SetMaxIndex(someArray,numBars);
Fill_Array(someArray,0);
It is my belief that I should not need the Fill_Array directive but that's a harmless old habit. Removing it does not seem to improve performance markedly.

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Dynamic Array - Performance

Postby JoshM » 09 Aug 2014

I find the performance on this to be terrible.
Can you define 'terrible performance'? Given that the array you use has only a size of four elements (or three, if you don't zero-based `ii`), I wonder how such a small array can cause so bad performance.

* * *

The performance of a dynamic array is around twice as slow as a fixed size array. With an array of 10,000 elements:

Code: Select all

Fixed size array took 7.2620 seconds.
Dynamic array took 14.5950 seconds.
Fixed size array took 7.2330 seconds.
Dynamic array took 14.5000 seconds.
Fixed size array took 7.2850 seconds.
Dynamic array took 14.5760 seconds.
Test code*:

Code: Select all

Variables:
oneSecondDT(ELTimeToDateTime_s(1)),
startTime(0), endTime(0), runTime(0),
arrayCount(10000), x(0), y(0);

Arrays:
fixedSize[10000](0),
dynamicArray[](0);

once (LastBarOnChart_s = true) begin

// Fixed array
for y = 0 to 50 begin

startTime = ComputerDateTime;

for x = 0 to arrayCount begin
fixedSize[x] = Random(10);
end;

for x = 0 to arrayCount begin
value1 = Array_Sum(fixedSize, 0, arrayCount);
end;

endTime = ComputerDateTime;
runTime = runTime + (endTime - startTime);

end;

Print("Fixed size array took ", NumToStr(runTime / oneSecondDT, 4), " seconds.");


// Dynamic array
for y = 0 to 50 begin

startTime = ComputerDateTime;

Array_SetMaxIndex(dynamicArray, arrayCount);

for x = 0 to arrayCount begin
dynamicArray[x] = Random(10);
end;

for x = 0 to arrayCount begin
value1 = Array_Sum(dynamicArray, 0, arrayCount);
end;

endTime = ComputerDateTime;
runTime = runTime + (endTime - startTime);

end;

Print("Dynamic array took ", NumToStr(runTime / oneSecondDT, 4), " seconds.");

end;
*: Don't click the MultiCharts program during this test. Apparently MultiCharts64 Version 8.8 Release (Build 8967) is not stable enough to do that without hanging.


But on-topic: if 10,000 array elements being summed give an execution time of 14,5 seconds, I doubt a little bit how your 3 elements array can give a terrible performance. Can perhaps something else in your code explain the poor performance?

Extrapolating from this small test, a 3 elements array should (in theory :) ) take 0.00145 seconds for both populating and calling the `Array_Sum()` keyword.
Last edited by JoshM on 09 Aug 2014, edited 1 time in total.

javamarket
Posts: 55
Joined: 10 Jul 2014
Has thanked: 10 times
Been thanked: 18 times

Re: Dynamic Array - Performance

Postby javamarket » 09 Aug 2014

Hi Josh,

Indeed what you have provided is close to my findings. The array in use is not as trivial as the example I previously provided, it was simplified for discussion. The actual array is trying to overcome this continuing disappointment between "data1 and data2" calculations.

These arrays are (relatively) large when back-testing is involved and this ~ 100% performance cost is impacting when the price scales are markedly different (e.g. 1min and 30min).

I do appreciate your posts.

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Dynamic Array - Performance

Postby JoshM » 09 Aug 2014

These arrays are (relatively) large when back-testing is involved and this ~ 100% performance cost is impacting when the price scales are markedly different (e.g. 1min and 30min).
What are your plans with the array by the way? I'm asking because, if you're interested in the array values on previous bars, you could also use the fact that variables can be indexed to retrieve the values of previous bars (just like `High`, `Close`, etc).

For example:

Code: Select all

Variables:
twoInARow(False),
threeInARow(False),
fourInARow(False);

if (BarStatus(1) = 2) then begin

twoInARow = (High < High[1]) and (High[1] < High[2]);
threeInARow = twoInARow and (High[2] < High[3]);
fourInARow = threeInARow and (High[3] < High[2]);

Print(
FormatDate("d-M", ELDateToDateTime(Date)),
FormatTime(" HH:mm:ss", ELTimeToDateTime_s(Time_s)),
", two? ", twoInARow,
", three? ", threeInARow,
", four? ", fourInARow);

// Referencing previous bar variable values
Print(Spaces(10),
"Two? ", twoInARow[1],
", three? ", threeInARow[1],
", four? ", fourInARow[1]);

end;
Which gives an output like:

Code: Select all

8-8 18:05:00, two? TRUE, three? FALSE, four? FALSE
Two? FALSE, three? FALSE, four? FALSE
8-8 18:35:00, two? FALSE, three? FALSE, four? FALSE
Two? TRUE, three? FALSE, four? FALSE
8-8 19:05:00, two? FALSE, three? FALSE, four? FALSE
Two? FALSE, three? FALSE, four? FALSE
8-8 19:35:00, two? FALSE, three? FALSE, four? FALSE
Two? FALSE, three? FALSE, four? FALSE
8-8 20:05:00, two? TRUE, three? FALSE, four? FALSE
Two? FALSE, three? FALSE, four? FALSE
8-8 20:35:00, two? FALSE, three? FALSE, four? FALSE
Two? TRUE, three? FALSE, four? FALSE
In this case, you'd only need to add an if-else statement based on the `NumBars` input to store the 'consecutive lower lows'-values in a variable, that then can indexed like an array to get the values of previous bars.

That would save you the performance loss of dynamic array, and probably also reduces the amount of code. If you're interested in the values on previous bars on close, of course. :]


Return to “MultiCharts”