DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Unexpected performance gain/hit

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

0 Kudos
Message 1 of 6
(5,557 Views)

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".

 

Navigator.png

 

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

 

 

0 Kudos
Message 2 of 6
(5,547 Views)

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

0 Kudos
Message 3 of 6
(5,539 Views)

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

 

 

0 Kudos
Message 4 of 6
(5,524 Views)

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.

 

0 Kudos
Message 5 of 6
(5,520 Views)

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

0 Kudos
Message 6 of 6
(5,507 Views)