02-21-2013 06:37 AM
I am using a for loop to step through the elements in a channel and look for a rising or falling edge. It works fine.
What I have noticed though is that I can hugely (~100x) speed up the operation by first scaling the channel with a factor of 1:
chnlinscale("/[1]","/[1]",1)
Has anybody else seen this or can anybody explain this to me please?
Thank you,
Martin
02-21-2013 08:21 AM
Hello Martin,
The reason can be the load behavior of the NAVIGATOR. DIAdem supports 3 different types. You find detailed information in the DIAdem help. In your case you can use "Always load ..." or "Load bulk data on first access".
By the way, I'm sure that you already know that the fastest access to a channel value is the Data-API. Here is a small example:
dim oChn
set oChn = Data.GetChannel("myGroup/myChannel")
oChn(i) = myNewValue
Greetings
Walter
02-21-2013 09:54 AM
Hi Martin,
You can speed this up even more by using the ChnCalculate() or ChnFind() functions to identify or find the feature you're interested in. These commands execute MUCH faster than an interpreted VBScript loop over all the channel values.
Brad Turpin
DIAdem Product Support Engineer
National Instruments
02-22-2013 02:29 AM
Hi there,
Thank you both for the help, it is very much appreciated. I had forgotten about the bulk load options and the effect that it has, I couldn't understand what was happening.
I tried running some different rising/falling edge detect algorithms on a channel I had. It was 900,000 elements long with about 850 rising and 850 falling edges.
I found the edges using an elseif statement to step through and compare each new value with the last, and with the ChnFind fucntion. I then also used a select statement and another elseif statement where I knew the high and low values were 1-0 so it made the calculation simpler.
What I found is that they were all really fast, looping through the elements with the elseif took about 2.3s, using ChnFind about 2.1s, this is on my standard work laptop. The select statement with 1-0 transition was the fastest, taking only 1.3s.
I'm very happy with these speeds but if there are ways I can improve this I'd be pleased to hear as it is something I do quite a lot on much bigger datasets.
Thanks again,
Martin
set chn = Data.GetChannel("[1]/[1]")
stopwatchreset()
'Run one of the methods and check the time
'using_elseif() '2.3s
'using_chnfind() '2.1s'
'using_elseif_one_zero() '1.5s
using_select_one_zero() '1.3s
Call MsgBoxDisp("Elapsed: "+Str(Stopwatch(1),"d.dd")+"s")
redim preserve result(1,j-1)
call arraytochannels(result,array("/rising","/falling"),true)
'----------------------
sub using_chnfind()
dim edge: edge=1
do while edge < chn.size and edge>0
edge = ChnFind("Ch(""[1]/[1]"")>0.5",edge)
if edge >0 then result(RISING,j) = edge
edge = ChnFind("Ch(""[1]/[1]"")<0.5",edge)
if edge > 0 then
result(FALLING,j) = edge
j=j+1
end if
loop
end sub
sub using_elseif
dim i,started : started = false
for i=2 to chn.Size
if chn(i) > 0.5 and chn(i-1) < 0.5 then 'rising edge
result(RISING,j) = i
started = true
elseif chn(i) < 0.5 and chn(i-1) > 0.5 and started = true then 'falling edge
result(FALLING,j)=i
j=j+1
end if
next
end sub
sub using_elseif_one_zero
dim dv,i,started : started = false
for i = 2 to chn.Size
dv = chn(i) - chn(i-1)
if dv = 1 then 'rising edge
result(RISING,j) = i
started = true
elseif dv = -1 and started = true then 'falling edge
result(FALLING,j)=i
j=j+1
end if
next
end sub
sub using_select_one_zero
dim i,dv,started : started = false
for i = 2 to chn.Size
dv = chn(i) - chn(i-1)
select case dv
case 1 'rising edge
result(RISING,j) = i
started = true
case -1 'falling edge
if started then
result(FALLING,j)=i
j=j+1
end if
case else
end select
next
end sub
02-22-2013 02:46 AM
I meant to say, I realise the benefit of the ChnFind function is probably not going to be seen on such a simple search criteria.
02-22-2013 11:34 AM
Hi Martin,
Those benchmarks are very interesting. I would have guessed the ChnFind() function would have been much faster. How many data points do you have per cycle (assuming the time between nearest rising edges is one cycle)? I think that's the critical metric, not the length of the channel. I would guess that ChnFind() would be much faster as the number of points per cycle got bigger than 100, say.
Brad Turpin
DIAdem Product Support Engineer
National Instruments