Benchmark wave access with *lots* of waves

/// @name Parameters for gnoise and enoise
///@{
Constant NOISE_GEN_LINEAR_CONGRUENTIAL = 1 ///< Don't use for new code.
Constant NOISE_GEN_MERSENNE_TWISTER    = 2
///@}

/// @brief Random shuffle of the wave contents
///
/// Function was taken from: http://www.igorexchange.com/node/1614
/// author s.r.chinn
///
/// @param inwave The wave that will have its rows shuffled.
/// @param noiseGenMode [optional, defaults to #NOISE_GEN_LINEAR_CONGRUENTIAL] type of RNG to use
Function InPlaceRandomShuffle(inwave, [noiseGenMode])
    wave inwave
    variable noiseGenMode

    variable i, j, emax, temp
    variable N = DimSize(inwave, 0)

    if(ParamIsDefault(noiseGenMode))
        noiseGenMode = NOISE_GEN_LINEAR_CONGRUENTIAL
    endif

    for(i = N; i>1; i-=1)
        emax = i / 2
        j =  floor(emax + enoise(emax))     //  random index
//      emax + enoise(emax) ranges in random value from 0 to 2*emax = i
        temp        = inwave[j]
        inwave[j]   = inwave[i-1]
        inwave[i-1] = temp
    endfor
end

Function/S MakeName(index)
    variable index

    string name
    sprintf name, "W_%010d", index

    return name
End

Function BenchmarkWaveAccess()

    KillDataFolder/Z root:

    variable numWaves = 1e5
    variable numTrials = 1e4
    variable numRuns = 1
    variable i, now, j, globalnow
    string name

    Make/O/N=(numWaves) timing = 0
    Make/O/N=(numWaves) indizes = p

    SetrandomSeed/BETR=1 1
    Inplacerandomshuffle(indizes, noiseGenMode=NOISE_GEN_MERSENNE_TWISTER)

    for(i = 0; i < numWaves; i += 1)
        Make/O/N=10000 $MakeName(i)
    endfor

    globalnow = stopmstimer(-2)
    for(i = 0; i < numTrials; i += 1)

        if(mod(i, numTrials*0.01) == 0)
            printf "%g\r" (i/numTrials) * 100
        endif

        now = stopmstimer(-2)
        for(j = 0; j < numRuns; j += 1)
            WAVE wv = $MakeName(indizes[i])
        endfor
        timing[indizes[i]] = (stopmstimer(-2) - now)/1e6/numRuns
    endfor
    printf "elapsed time %g\r", (stopmstimer(-2) - globalnow)/1e6/numRuns
End

 

Warning: Inspect the code before running it as it takes quite a bit of RAM.

After running BenchmarkWaveAccess() call Display timing.

Graph0.pdf

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More