-
Dec 18th, 2017, 02:54 AM
#1
Thread Starter
Junior Member
[RESOLVED] High accuracy timer / delay
Hey I'm quite the beginner in VB.NET so I don't know all the possibilities with the problem I'm having.
I'm currently using the default VB.NET timer control, however after a few weeks of testing quite thoroughly I discovered that my delay was longer than it was supposed to be.
Let me explain my situation:
I am receiving values over my serial port which I then write to a chart so that I get a line curve (Spline). I add the chart points with my timer. Every 50 milliseconds I add a new values received by my serial port. This value is also added to my datagridview. so I can build up a nice grid overview including my system time (the time given by my computer itself).
After a while using my program I discovered that the time is quite off. I used a stopwatch to time my actions and after 10 seconds I noticed that it were actually ~13 seconds in reality. I somewhere read that the VB.NET timers are not actually that precise even if you can input intervals of 1 ms. Apparently I need a high resolution timer to solve my problem, so here I am wondering what path to follow.
I've read about a function called stopwatch, however I do not need a time between start and end, I need an accurate delay / timer.
Any suggestions / idea's how I could solve my problem? Also if anything is unclear I happily will try to clear it up. Help would be VERY much appreciated!
-
Dec 18th, 2017, 05:27 AM
#2
Addicted Member
Re: High accuracy timer / delay
Hello,
Maybe something like this could help you out;
Code:
Imports System.ComponentModel
Public Class Form1
Private WithEvents Bgw As New ComponentModel.BackgroundWorker
Private WithEvents St As New Diagnostics.Stopwatch
Private Event Tick(Ms As Integer)
Private CancelBgw As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
With Bgw
.WorkerSupportsCancellation = True
If Not .IsBusy Then
CancelBgw = False
.RunWorkerAsync()
End If
End With
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Me.CancelBgw = True
End Sub
Private Sub Bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles Bgw.DoWork
St.Start()
While Not Me.CancelBgw
If St.ElapsedMilliseconds >= 50 Then
RaiseEvent Tick(St.ElapsedMilliseconds)
St.Reset()
St.Start()
End If
End While
End Sub
Private Sub Form1_Tick(Ms As Integer) Handles Me.Tick
Debug.Print(Ms.ToString)
End Sub
End Class
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 05:32 AM
#3
Re: High accuracy timer / delay
This is a well presented question, however we need details of how you're using the timer (timers).
There are guys in this forum that will sort out your problem, but they're all going to need to see the relevant coding.
Poppa.
Along with the sunshine there has to be a little rain sometime.
-
Dec 18th, 2017, 06:54 AM
#4
Thread Starter
Junior Member
Re: High accuracy timer / delay
Originally Posted by Goggy
Hello,
Maybe something like this could help you out;
Code:
Imports System.ComponentModel
Public Class Form1
Private WithEvents Bgw As New ComponentModel.BackgroundWorker
Private WithEvents St As New Diagnostics.Stopwatch
Private Event Tick(Ms As Integer)
Private CancelBgw As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
With Bgw
.WorkerSupportsCancellation = True
If Not .IsBusy Then
CancelBgw = False
.RunWorkerAsync()
End If
End With
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Me.CancelBgw = True
End Sub
Private Sub Bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles Bgw.DoWork
St.Start()
While Not Me.CancelBgw
If St.ElapsedMilliseconds >= 50 Then
RaiseEvent Tick(St.ElapsedMilliseconds)
St.Reset()
St.Start()
End If
End While
End Sub
Private Sub Form1_Tick(Ms As Integer) Handles Me.Tick
Debug.Print(Ms.ToString)
End Sub
End Class
I have tried to add this code, however it did not work out the way I hoped for. There is something blocking a second loop.
Luckily you are dutch (I assume because of your signature :P) so maybe you will understand some of my coding.
Code:
Private Sub drawchart()
receivedSerialData = ReceiveSerialData()
Dim lines As String() = receivedSerialData.Split(vbLf)
If lines(0).Length > 3 Then
Double.TryParse(lines(0), analoge)
End If
Dim eindwaarde = (analoge / 5) - offset
If SerialPort1.IsOpen = True Then
If Chart1.Series(0).Points.Count > Val(maxval) Then
Chart1.Series(0).Points.RemoveAt(0)
End If
DataGridView1.Rows.Insert(0, DateTime.Now.ToString("dd/MM/yyyy--HH:mm:ss"), eindwaarde, gridid)
Chart1.Series(0).Points.AddY(eindwaarde)
gridid = Val(gridid) + 1
Else
SerialPort1.Open()
End If
End Sub
I added this at the me.tick event.
Thanks for your example though I will try and figure out more about this method!
Originally Posted by Poppa Mintin
This is a well presented question, however we need details of how you're using the timer (timers).
There are guys in this forum that will sort out your problem, but they're all going to need to see the relevant coding.
Poppa.
I wouldn't mind showing relevant code. Please tell me what I should add (other than the code I presented above).
-
Dec 18th, 2017, 07:10 AM
#5
Addicted Member
Re: High accuracy timer / delay
what do you mean "There is something blocking a second loop." ?
Does the tick event only happens once? or does the code get hang up in the tick event? Or is the code producing an error?
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 07:12 AM
#6
Thread Starter
Junior Member
Re: High accuracy timer / delay
In the debug I can only see one cycle of code. Lets say I see the 50 ms debug once and then it just stops. The program doesn't crash or show any error.
Edit: sorry it shows: Exception thrown: 'System.InvalidOperationException' in System.Windows.Forms.dll
-
Dec 18th, 2017, 07:14 AM
#7
Addicted Member
Re: High accuracy timer / delay
would you be so kind as to put a try catch statement accross the tick event? and then see if it still doenst produce an error
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 07:18 AM
#8
Thread Starter
Junior Member
Re: High accuracy timer / delay
Originally Posted by Goggy
would you be so kind as to put a try catch statement accross the tick event? and then see if it still doenst produce an error
Sure thing, the result: it does keep up the loop now + "Exception thrown: 'System.InvalidOperationException' in System.dll".
So right now I have:
Code:
Private Sub Form1_Tick(Ms As Integer) Handles Me.Tick
Try
Debug.Print(Ms.ToString)
drawchart()
Catch
End Try
End Sub
Code:
Private Sub drawchart()
receivedSerialData = ReceiveSerialData()
Dim lines As String() = receivedSerialData.Split(vbLf)
If lines(0).Length > 3 Then
Double.TryParse(lines(0), analoge)
End If
Dim eindwaarde = (analoge / 5) - offset
If SerialPort1.IsOpen = True Then
If Chart1.Series(0).Points.Count > Val(maxval) Then
Chart1.Series(0).Points.RemoveAt(0)
End If
DataGridView1.Rows.Insert(0, DateTime.Now.ToString("dd/MM/yyyy--HH:mm:ss"), eindwaarde, gridid)
Chart1.Series(0).Points.AddY(eindwaarde)
gridid = Val(gridid) + 1
Else
SerialPort1.Open()
End If
End Sub
-
Dec 18th, 2017, 07:34 AM
#9
Re: High accuracy timer / delay
-
Dec 18th, 2017, 07:35 AM
#10
Addicted Member
Re: High accuracy timer / delay
Ok , i susspect it has to do with cross threading, trying to update the form thread from the background worker thread....
mmmm...
ok lets try it like so
Code:
Public Class Form1
Private WithEvents Bgw As New ComponentModel.BackgroundWorker
Private WithEvents St As New Diagnostics.Stopwatch
Private Event Tick(Ms As Integer)
Private CancelBgw As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
With Bgw
.WorkerReportsProgress = True '<----Added
.WorkerSupportsCancellation = True
If Not .IsBusy Then
CancelBgw = False
.RunWorkerAsync()
End If
End With
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Me.CancelBgw = True
End Sub
Private Sub Bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles Bgw.DoWork
St.Start()
While Not Me.CancelBgw
If St.ElapsedMilliseconds >= 50 Then
Bgw.ReportProgress(1) '<----Added (Its a bit of an hack)
'RaiseEvent Tick(St.ElapsedMilliseconds) '<----Removed
St.Reset()
St.Start()
End If
End While
End Sub
'Private Sub Form1_Tick(Ms As Integer) Handles Me.Tick
' Debug.Print(Ms.ToString)
'End Sub
Private Sub Bgw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles Bgw.ProgressChanged
'Result beeing that the drawchart sub is called from the ui thread.
drawchart
End Sub
End Class
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 08:04 AM
#11
Thread Starter
Junior Member
Re: High accuracy timer / delay
Originally Posted by Goggy
Ok , i susspect it has to do with cross threading, trying to update the form thread from the background worker thread....
mmmm...
ok lets try it like so
Code:
Public Class Form1
Private WithEvents Bgw As New ComponentModel.BackgroundWorker
Private WithEvents St As New Diagnostics.Stopwatch
Private Event Tick(Ms As Integer)
Private CancelBgw As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
With Bgw
.WorkerReportsProgress = True '<----Added
.WorkerSupportsCancellation = True
If Not .IsBusy Then
CancelBgw = False
.RunWorkerAsync()
End If
End With
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Me.CancelBgw = True
End Sub
Private Sub Bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles Bgw.DoWork
St.Start()
While Not Me.CancelBgw
If St.ElapsedMilliseconds >= 50 Then
Bgw.ReportProgress(1) '<----Added (Its a bit of an hack)
'RaiseEvent Tick(St.ElapsedMilliseconds) '<----Removed
St.Reset()
St.Start()
End If
End While
End Sub
'Private Sub Form1_Tick(Ms As Integer) Handles Me.Tick
' Debug.Print(Ms.ToString)
'End Sub
Private Sub Bgw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles Bgw.ProgressChanged
'Result beeing that the drawchart sub is called from the ui thread.
drawchart
End Sub
End Class
With this code it does work, but I think due to it being on another thread It's now having problems updating the datagrid as well.
Currently the chart is working very fluently when my datagrid is "hidden" (I have a button to expand my form and it will show the list of values in the datagrid). When I expand my form and open up my datagridview the chart is starting to lag very badly until I close the expanded part again.
Code:
Private Sub drawchart()
~~~~~~
DataGridView1.Rows.Insert(0, DateTime.Now.ToString("dd/MM/yyyy--HH:mm:ss"), eindwaarde, gridid)
~~~~~~
end sub
-
Dec 18th, 2017, 08:23 AM
#12
Addicted Member
Re: High accuracy timer / delay
how many rows are there in the datagrid?
I guess its taking up more then 50 ms to insert the row.
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 08:38 AM
#13
Thread Starter
Junior Member
Re: High accuracy timer / delay
Well every 50 ms a new gets added. Sometimes there are over 50k rows. Would this be the bottleneck? Any advice on this?
-
Dec 18th, 2017, 08:43 AM
#14
Addicted Member
Re: High accuracy timer / delay
Maybe save the data to a database, and only show the last 100 rows or so?
Utterly useless, but always willing to help
As a finishing touch god created the dutch
-
Dec 18th, 2017, 09:41 AM
#15
Re: High accuracy timer / delay
Good hardware has a clock and clocks itself with a degree of accuracy you pay for. I worked at a test and measurement company for a long time, and generally the sample rate was just part of configuring communication with our devices. The really good ones could sample down to the nanosecond range. You can't make the WinForms timer do this. It's designed to be polite when the machine is under stress. That means you can never guarantee you get events at the interval you want. If the work you do takes longer than a timer interval, you miss intervals. You can't get around that.
Part of acquiring data is presenting it, and even when the hardware supports clocking if the data arrives faster than you can display it, you lag. 50ms intervals are a little too fast, in my opinion, to expect real-time display, especially considering getting your data from "raw" to "DataGridView" probably involves several transformations, both explicit and implicit.
When sample rate exceeds processing speed, you have to buffer. That's something good hardware does automatically as well, but often you can get cheaper versions of good hardware that don't buffer. All it really means is instead of this:
Code:
Every 50ms:
* Get a sample.
* Display a sample.
You switch to something like this:
Code:
Every 50ms:
* (Worker thread.) Get a sample and store it.
Every 5s:
* (UI thread.) Get all current samples and display them.
This way, your UI logic doesn't interfere with your sampling logic, and if it takes slightly longer to process data than acquire it you can find a way to manage. This is how that nanosecond hardware I mentioned HAS to operate: few machines can process and display data in the GB range per second. So they sample for a second or two, dumping samples into a buffer, then they take their sweet time processing the data in the buffer and display it.
So if hardware clocking/buffering isn't an option, you should make a thread to do your buffering. It should sample at 50ms using System.Threading.Timer, but you need to keep in mind that one doesn't guarantee 50ms either. So you should also timestamp your data so you understand the true sample delta. (This is another thing good hardware/drivers do for you.)
The UI thread should periodically empty the buffer, process the data, and display it. This interval should be much slower, 1-2s seems reasonable.
This falls apart if it takes you more than 50ms of processing per data point. If that is true, you need to either consider "sample for some time, then stop sampling and wait for processing to catch up" or "cut the sample rate to 100ms or higher until processing catches up", or "It's OK to drop some points if we're behind", etc. You'll run out of memory if you don't pick a "backpressure" strategy.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 18th, 2017, 09:42 AM
#16
Re: High accuracy timer / delay
What does method 'ReceiveSerialData' look like? If it contains a blocking serial port method then that will affect your timer.
edit: See sitten made a suggestion at the same time, and I totally agree about the structure he is recommending.
-
Dec 18th, 2017, 09:48 AM
#17
Thread Starter
Junior Member
Re: High accuracy timer / delay
Taken your two replies I could store my UI data from the datagrid into an array and display this one based on a different timer / thread. This way the chart is accurate which is the most important part, due to being the soul purpose of this application.
Storing it in a database itself (I'm thinking about MySQL or something when I see the word database, correct me if I'm wrong), wouldn't be something I could do due to this program being on multiple machines in various locations without internet connection.
Thanks for all the help you guys gave me. I will try and see how it goes when I separate the chart from the grid!
-
Dec 18th, 2017, 09:49 AM
#18
Re: High accuracy timer / delay
I was just revisiting this subject a week or so ago because of another thread.
Depending on how much jitter is acceptable, the following is some test code that just uses the timer running as fast as it can (which won't take too much CPU), and using a stopwatch to monitor the passage of time. The code assumes the timer will be running at least 64 hz (15.625ms interval) so uses approximately half of that value (8 ms) as a threshold. If the timer tick is within +/- 8 ms of the desired trigger time you should execute your code and add the desired interval to your trigger time.
Since the timer ticks occur on the GUI thread, you won't have cross threading issues to deal with.
Here is a sample output of the example (you would remove all that debug stuff in your usage). In this case we wanted to execute every 50ms for a period of 3 seconds.
The expected result would be 20 times per second for 3 seconds would be 60 executions over a period of 3000ms.
The printout counts the runs, the time that it executed, the ideal desired time ("Trigger"), the delta between when when it ran vs the ideal time it should have run.
It also shows ticks where the processing was skipped to achieve the desired rate.
Code:
Process 55 Ran at 2753ms elapsed time, Trigger 2750, delta 3
Skipping this timer tick
Skipping this timer tick
Process 56 Ran at 2793ms elapsed time, Trigger 2800, delta -7
Skipping this timer tick
Skipping this timer tick
Process 57 Ran at 2843ms elapsed time, Trigger 2850, delta -7
Skipping this timer tick
Skipping this timer tick
Process 58 Ran at 2893ms elapsed time, Trigger 2900, delta -7
Skipping this timer tick
Skipping this timer tick
Skipping this timer tick
Process 59 Ran at 2953ms elapsed time, Trigger 2950, delta 3
Skipping this timer tick
Skipping this timer tick
Process 60 Ran at 3003ms elapsed time, Trigger 3000, delta 3
Process ran 60 times, taking 3003ms
You see the process ran the desired 60 times over a period of 3003 ms, so only + 3 ms over ideal. That +3 ms over is not accumulative, so if you ran six seconds or sixty seconds, you would still be within a portion of a timer tick of the correct time, and have executed the number of times desired over that period.
Code:
Public Class Form1
Private DesiredTickInterval As Integer 'interval in ms
Private DesiredTime As Long 'How long we want to process in ms
Private TriggerTime As Long 'Updated to define when we should process next
Private sw As New Stopwatch
Private ProcessRuns As Integer
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
sw.Reset()
DesiredTickInterval = 50 '50ms means process 20 times per second
TriggerTime = DesiredTickInterval 'intialize first trigger
ProcessRuns = 0
DesiredTime = 3000 'process for 3 second
Timer1.Interval = 1 'let timer fire as quick as it can (probably 64 times per second)
Timer1.Start() 'start the timer
sw.Start() 'start our elapsed time stopwatch
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim currentElapsedTime As Long = sw.ElapsedMilliseconds
Dim deltaTime As Long = currentElapsedTime - TriggerTime
If (currentElapsedTime >= TriggerTime) Or
(Math.Abs(deltaTime) <= 8) Then 'allow to happen a little before or after the desired time, so a little steadier
ProcessRuns += 1
Debug.Print("Process {1} Ran at {0}ms elapsed time, Trigger {2}, delta {3}",
currentElapsedTime.ToString, ProcessRuns.ToString, TriggerTime.ToString, deltaTime.ToString)
TriggerTime += DesiredTickInterval 'update our trigger for the next desired time
Else
Debug.Print("Skipping this timer tick")
End If
If currentElapsedTime >= DesiredTime Then
sw.Reset()
Timer1.Stop()
Debug.Print("Process ran {0} times, taking {1}ms", ProcessRuns.ToString, currentElapsedTime.ToString)
End If
End Class
p.s. Several posts while I was digging this up. I do agree with SittenSpynne and normally do separate the data processing from the GUI updates as well, but in other cases I do need a relatively stable trigger for updating Simulation models at a given number of times per second within acceptable jitter and use a method like the above to achieve that in simple scenarios. In more stringent requirements, then the trigger is tied to a real hardware backed solution as he mentioned, e.g. a hardware based realtime clock card or a video based start of frame message.
Last edited by passel; Dec 18th, 2017 at 10:05 AM.
Reason: Removed unused variable from Timer tick sub
-
Dec 18th, 2017, 04:58 PM
#19
Re: High accuracy timer / delay
If you have a timer set to fire every 10 seconds and then it performs a 1 second operation it will effectively delay the timer for a second ... so then when it comes to wait again you will be 1 second out ... then 2 etc.
There are ways to do this with threads etc ... but just say you want to update something every 50ms and you have operations that fire off evey 50 ms on another thread ... but the operations on a slower computer take 1 second to run ... if you do this you can run into resource issues as more and more threads are created on the computer that can't keep up, each one potentially running slower than the last!
Since this is an interface you may be tempted to run a thread timer and invoke the form ... this will be accurate but can also produce the issue of delay between tick and execution ... if the computer is too slow to execute the commands before the next interval... these are internally BeginInvoked ... so this will queue up and cause the same issue.
I think that the best solution (with such a small delay updating an interface) would be to either store the data with a small interval on a thread timer (every 50ms) - but store the time with it as a safeguard .. so if somehow a few ms/s are missed as getting the data takes longer in one instance takes a little longer, it can be plotted a little bit "off its point"... Just storing the data would prob be fast ... I would then prob invoke an update to the graph that happens every so often ... lets say 250ms ... from the same thread timer.
Structure for storing the queued points:
VB.Net Code:
Public Structure DataValues Public ReadOnly Property Time As Date Public ReadOnly Property Value As Integer Public Sub New(Time As Date, Value As Integer) Me.Time = Time : Me.Value = Value End Sub End Structure
Your thread timer event code could look like this:
VB.Net Code:
Static QueuedPoints As New List(Of DataValues) Static LastDrawnTime As Date 'add to QueuedPoints here QueuedPoints.Add(New DataValues(Now, value)) 'update the graph if last drawn more than 250ms ago If Now.Subtract(LastDrawnTime).TotalMilliseconds >= 250 Then LastDrawnTime = Now 'me is the form you want to invoke... 'we need to pass the queued points into it as an array so we can clear it on this thread while the graph is updating Me.BeginInvoke(Sub(qp As DataValues()) 'update graph with queued points here End Sub, QueuedPoints.ToArray) QueuedPoints.Clear() End If
... Value above would be your new value for the graph
Kris
-
Dec 18th, 2017, 05:06 PM
#20
Re: High accuracy timer / delay
Actually since this is presumably not time critical and just for updating the graph I would prob do it the way you are doing now ... and just store the last tick and the new tick in some way (either as a time / stopwatch etc) and use that to get the interval between the points ... rather than assuming that they will be 50ms
Kris
-
Dec 18th, 2017, 05:12 PM
#21
Thread Starter
Junior Member
Re: High accuracy timer / delay
Currently I store the data for my grid in an array list. This way I do save the important information for my grid, but the actual control (datagridview) is updated when I stop the timer interval of 50 ms. This way I get both what I want with the precision that I want. Thank you all for your kind suggestions
-
Dec 18th, 2017, 05:26 PM
#22
Re: High accuracy timer / delay
You should consider using a specifically-typed List(Of T) instead of an ArrayList.
ArrayList has been obsolete since .NET 2.0, which was VS 2005. Any book or tutorial that uses it is a good candidate for "out of date enough to be irrelevant". It stores items as the type "Object". That's not a "real" type for many things. If you're storing Doubles or Integers or other certain kinds of type, that means before you get to actually use them, a process called "unboxing" has to occur. Performance penalties incurred by boxing/unboxing used to be one of the biggest problems in .NET. It was the sole motivation for Generics. Then Microsoft got really excited about designing frameworks that ignore it so no one really thinks about it anymore.
But if you're doing DAQ with lots of samples, you ought to get a nice performance boost out of using List(Of Double) instead of, say, an ArrayList with Doubles inside. Also: internally both ArrayList and List(Of T) resize themselves in powers of two. So it starts with a capacity of 16 by default, then resizes to 32 when you add the 17th item, resizes to 64 when you add the 33rd item, and so on. These resizes are very expensive, so you want to minimize them. If you expect 1000 samples, pre-set your capacity to 1024 or so for a margin. If you expect 10,000, go ahead and pre-set the capacity to 11,000 or so.
Switching away from ArrayList and pre-setting the capacity ought to bring about more consistent performance.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 19th, 2017, 05:56 AM
#23
Thread Starter
Junior Member
Re: High accuracy timer / delay
Originally Posted by Sitten Spynne
You should consider using a specifically-typed List(Of T) instead of an ArrayList.
ArrayList has been obsolete since .NET 2.0, which was VS 2005. Any book or tutorial that uses it is a good candidate for "out of date enough to be irrelevant". It stores items as the type "Object". That's not a "real" type for many things. If you're storing Doubles or Integers or other certain kinds of type, that means before you get to actually use them, a process called "unboxing" has to occur. Performance penalties incurred by boxing/unboxing used to be one of the biggest problems in .NET. It was the sole motivation for Generics. Then Microsoft got really excited about designing frameworks that ignore it so no one really thinks about it anymore.
But if you're doing DAQ with lots of samples, you ought to get a nice performance boost out of using List(Of Double) instead of, say, an ArrayList with Doubles inside. Also: internally both ArrayList and List(Of T) resize themselves in powers of two. So it starts with a capacity of 16 by default, then resizes to 32 when you add the 17th item, resizes to 64 when you add the 33rd item, and so on. These resizes are very expensive, so you want to minimize them. If you expect 1000 samples, pre-set your capacity to 1024 or so for a margin. If you expect 10,000, go ahead and pre-set the capacity to 11,000 or so.
Switching away from ArrayList and pre-setting the capacity ought to bring about more consistent performance.
Thank you for the information. I now use a list of strings to collect all the data for my datagridview. Upon completion of the serialport data it will put all the datagrid data in the list. This method seems to working very quick and has good results so far.
Thank you all for helping me out here!
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|