Announcement
Collapse
No announcement yet.
Partner 728x90
Collapse
NinjaTrader
OnRender() Performance Booster
Collapse
X
-
OnRender() Performance Booster
Hi, I have a basic question: does it make sense to use a foreach loop in OnRender(), to outsource the content to multiple tasks? If a lot of data is loaded in the chart, the chart starts to jerk and the mouse movements are also no longer fluid. Could this perhaps improve with the division of the work to several tasks? -
Hi Jesse, thank you for your answer.
Let's assume that a lot of lines are drawn in this method. Would it make sense here if each list entry were calculated in a separate task?Code:foreach (var kvp in xyToDraw.ToList()) {[INDENT]DrawXy(chartControl, chartScale, kvp.Value);[/INDENT] }
Comment
-
Hello sidlercom80,
Yes that would be a good use for a loop. Just to clarify the loop is going to do those one after another the same as if you had manually typed out a bunch of lines of code. The only efficiency gained here is less code because it is still the same work being done, the loop just automates the repetitive parts.
Comment
-
Is there no other way to access the member data of xyToDraw?Originally posted by sidlercom80 View PostHi Jesse, thank you for your answer.
Let's assume that a lot of lines are drawn in this method. Would it make sense here if each list entry were calculated in a separate task?Code:foreach (var kvp in xyToDraw[COLOR=#e74c3c].ToList()[/COLOR]) {[INDENT]DrawXy(chartControl, chartScale, kvp.Value);[/INDENT] }
I mean, is that ToList() really necessary?
Comment
-
Hi bltdavid, no it's also possible without, it's only an example, why?Originally posted by bltdavid View Post
Is there no other way to access the member data of xyToDraw?
I mean, is that ToList() really necessary?
That still does not answer the question ;-) do you know perhaps an example in OnRender() a foreach loop with a task or similar was worked?
Comment
-
Hi, I have another understanding question: which is the better solution? To do the .Dispose after every RenderTarget, or is it enough once at the end of the method?
Which type needs less resources (memory and CPU)?
Code:TextFormat tf = new TextFormat(new Factory(), sf.Family.ToString(), SharpDX.DirectWrite.FontWeight.Bold, SharpDX.DirectWrite.FontStyle.Normal, (float)sf.Size + 2); TextLayout tl = null; ... tl = new TextLayout(Globals.DirectWriteFactory, "Test1", tf, 100, 20); RenderTarget.DrawTextLayout(vec1, tl, "TestColor"); ... tl = new TextLayout(Globals.DirectWriteFactory, "Test2", tf, 100, 20); RenderTarget.DrawTextLayout(vec1, tl, "TestColor"); ... tf.Dispose(); tl.Dispose();
Code:TextFormat tf = new TextFormat(new Factory(), sf.Family.ToString(), SharpDX.DirectWrite.FontWeight.Bold, SharpDX.DirectWrite.FontStyle.Normal, (float)sf.Size + 2); TextLayout tl = null; ... tl = new TextLayout(Globals.DirectWriteFactory, "Test1", tf, 100, 20); RenderTarget.DrawTextLayout(vec1, tl, "TestColor"); tl.Dispose(); ... tl = new TextLayout(Globals.DirectWriteFactory, "Test2", tf, 100, 20); RenderTarget.DrawTextLayout(vec1, tl, "TestColor"); tl.Dispose(); ... tf.Dispose();
Comment
-
Hello sidlercom80,
The most efficient way to create resources that are shared would be to use OnRenderTargetChanged. For items that need created dynamically or require specific rendering items like X/Y values you would just create and dispose of those objects in OnRender. Where you dispose of that in OnRender doesn't really matter as long as it is disposed. Your first example is missing a dispose because you assign the variable twice but dispose once so 1 resource is left in memory.
- Likes 1
Comment
-
Let's be blunt.Originally posted by sidlercom80 View Post[CODE}foreach (var kvp in xyToDraw.ToList())
{DrawXy(chartControl, chartScale, kvp.Value);
}
[/CODE]
Let's assume that a lot of lines are drawn in this method. Would it make sense here if each list entry were calculated in a separate task?
(You asked for more help in a private message, see that reply also.)
Have you studied every OnRender in the Indicators folder?
Do you see some very similar techniques?
Do those techniques look anything like what you're doing?
You've given very little of your code to study, so I'm going to make
the easy assumption that your OnRender fails to closely model
the OnRender techniques employed by NinjaTrader.
Not to mention, there is the fundamental question that kinda
bugs me -- why are you drawing lines? I mean, the standard
Ninja line drawing methods are handled automatically by the
internal OnRender -- what's so special that you gotta handle
your own line drawing in a custom OnRender?
Ok, you're right, legitimate cases do exist.
Let's study one of those.
Have you looked at @Pivots.cs?
It draws horizontal lines using a custom OnRender.
But look closely at the code, it does not paint every single
element of the line for every single bar in the bar series.
It only paints line elements for bars that are visible inside
the chart, starting at bar index 'ChartBars.FromIndex' and
ending at 'ChartBars.ToIndex'.
That is, the viewable canvas area can only show 'X' bars at
any one time. As a new bar is added on the right, the oldest
visible bar on the left scrolls off of the visible canvas, and you
still have 'X' bars viewable.
When your code DrawXy draws its lines, are you drawing
for all bars 0 to CurrentBar? That is wrong.
Your code should be doing its own 'clipping' of the lines that
need to be painted, and it should only issue draw commands
for the visible portions of those lines.
You may be doing all that already.
I may be completely off base.
But who knows?
The code you provided is completely inadequate to know anything
about what you are doing ... much less if it's right or wrong.
-=o=-
As far as using separate tasks, why do you think that will
make a difference? I've never seen any code do that, and
until you have timing benchmarks from a profiler telling you
where in the code all the time is being spent, thinking along
those lines (pun?) is premature and way overkill -- separate
tasks don't strike me as the most appropriate weapon for
this fight.
Last edited by bltdavid; 03-09-2022, 04:05 PM.
Comment
-
I don't draw all bars but only the visible ones, like in your example above. My request was a general question how to handle things in OnRender better and therefore faster. Whether it is at all possible to outsource things in task to increase the performance, or whether that is basically not possible.Originally posted by bltdavid View Post
Let's be blunt.
(You asked for more help in a private message, see that reply also.)
Have you studied every OnRender in the Indicators folder?
Do you see some very similar techniques?
Do those techniques look anything like what you're doing?
You've given very little of your code to study, so I'm going to make
the easy assumption that your OnRender fails to closely model
the OnRender techniques employed by NinjaTrader.
Not to mention, there is the fundamental question that kinda
bugs me -- why are you drawing lines? I mean, the standard
Ninja line drawing methods are handled automatically by the
internal OnRender -- what's so special that you gotta handle
your own line drawing in a custom OnRender?
Ok, you're right, legitimate cases do exist.
Let's study one of those.
Have you looked at @Pivots.cs?
It draws horizontal lines using a custom OnRender.
But look closely at the code, it does not paint every single
element of the line for every single bar in the bar series.
It only paints line elements for bars that are visible inside
the chart, starting at bar index 'ChartBars.FromIndex' and
ending at 'ChartBars.ToIndex'.
That is, the viewable canvas area can only show 'X' bars at
any one time. As a new bar is added on the right, the oldest
visible bar on the left scrolls off of the visible canvas, and you
still have 'X' bars viewable.
When your code DrawXy draws its lines, are you drawing
for all bars 0 to CurrentBar? That is wrong.
Your code should be doing its own 'clipping' of the lines that
need to be painted, and it should only issue draw commands
for the visible portions of those lines.
You may be doing all that already.
I may be completely off base.
But who knows?
The code you provided is completely inadequate to know anything
about what you are doing ... much less if it's right or wrong.
-=o=-
As far as using separate tasks, why do you think that will
make a difference? I've never seen any code do that, and
until you have timing benchmarks from a profiler telling you
where in the code all the time is being spent, thinking along
those lines (pun?) is premature and way overkill -- separate
tasks don't strike me as the most appropriate weapon for
this fight.

Comment
Latest Posts
Collapse
| Topics | Statistics | Last Post | ||
|---|---|---|---|---|
|
Started by Geovanny Suaza, 02-11-2026, 06:32 PM
|
0 responses
579 views
0 likes
|
Last Post
|
||
|
Started by Geovanny Suaza, 02-11-2026, 05:51 PM
|
0 responses
334 views
1 like
|
Last Post
|
||
|
Started by Mindset, 02-09-2026, 11:44 AM
|
0 responses
101 views
0 likes
|
Last Post
by Mindset
02-09-2026, 11:44 AM
|
||
|
Started by Geovanny Suaza, 02-02-2026, 12:30 PM
|
0 responses
554 views
1 like
|
Last Post
|
||
|
Started by RFrosty, 01-28-2026, 06:49 PM
|
0 responses
551 views
1 like
|
Last Post
by RFrosty
01-28-2026, 06:49 PM
|

Comment