Announcement
Collapse
Looking for a User App or Add-On built by the NinjaTrader community?
Visit NinjaTrader EcoSystem and our free User App Share!
Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less
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? -
Hello sidlercom80,
That depends on the task, in general you can use loops in OnRender to do something repetitive. I would not be able to say if in your specific use case if that will be helpful or not, I would need more details about what task you are trying to make have better performance.JesseNinjaTrader Customer Service
-
Hi Jesse, thank you for your answer.
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.
JesseNinjaTrader Customer Service
Comment
-
Originally posted by sidlercom80 View PostHi Jesse, thank you for your answer.
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
-
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.JesseNinjaTrader Customer Service
- Likes 1
Comment
-
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
-
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 adeelshahzad, Today, 11:49 AM
|
5 responses
15 views
0 likes
|
Last Post Today, 01:27 PM | ||
Started by spottysallrite, Today, 11:31 AM
|
5 responses
12 views
0 likes
|
Last Post Today, 01:20 PM | ||
Started by yaniv, Today, 12:50 PM
|
1 response
2 views
0 likes
|
Last Post Today, 01:15 PM | ||
Started by Lele2k24, Yesterday, 11:24 AM
|
10 responses
32 views
0 likes
|
Last Post Today, 01:04 PM | ||
Started by Padan, Today, 02:02 AM
|
7 responses
19 views
0 likes
|
Last Post Today, 12:59 PM |
Comment