[vtkusers] InsertNextValue as efficient as SetValue in Python?

Victor B. Putz vputz at nyx.net
Tue Dec 27 13:12:10 EST 2005


I'm trying to speed up the update of a vtkFloatArray in Python; it seems
to be taking an inordinate amount of time.

Conventional wisdom says that I should preallocate the array and use
SetValue.  To my surprise, this was A) not much more efficient and B) does
not seem to update the range or color map, so that visually nothing
changes between frames.

The second part I'll leave for later.  My question this time regards the
efficiency of SetValue vs InsertNextValue.

I wrote a small time trial script to compare three methods for setting all
the values of a vtkFloatArray:

Method 1: create the array and preallocate by using SetNumberOfValues(). 
In the main loop, just use SetValue() to set the value.  As stated in the
VTK documentation for SetNumberOfValues: "Used in conjunction with
SetValue() method for fast insertion"

Method 2: create a new vtkFloatArray every time you update and use
InsertNextValue to fill it with values.

Method 3: create a vtkFloatArray, use SetNumberOfValues to preallocate. 
In the main loop, Reset() the array and use InsertNextValue to fill with
values.

Doing 100 iterations on a 10000-point array, here are the comparative
benchmarks:

Method 1: 0.849515
Method 2: 0.854110
Method 3: 0.820987

Not only is allocating a new array almost as efficient as preallocating
and using SetValue(about 0.5 % difference), it is actually FASTER to
preallocate and use InsertNextValue.

Something seems very amiss.  What is going on--or better, what is the
fastest way to fill such an array in Python?

(script is attached)

-->VPutz
***BEGIN SIMPLE TIME TRIAL SCRIPT***
import vtk
import time

def time_trial() :
    # first try -- allocate the array first and
    # use SetValue -- this should be efficient!
    a = vtk.vtkFloatArray()
    a.SetNumberOfValues(10000)
    t1 = time.clock()
    for i in range(0,10000) :
        a.SetValue(i,i*2)
    t2 = time.clock()

    # second try--allocate a new array every time
    # and use InsertNextValue
    t3 = time.clock()
    a = vtk.vtkFloatArray()
    for i in range(0,10000) :
        a.InsertNextValue(i*2)
    t4 = time.clock()

    # third way--allocate an array, reset it, and
    # then use InsertNextValue
    a = vtk.vtkFloatArray()
    a.SetNumberOfValues(10000)
    t5 = time.clock()
    a.Reset()
    for i in range(0,10000) :
        a.InsertNextValue(i*2)
    t6 = time.clock()
    return (t1, t2, t3, t4, t5, t6)

#now just do 100 trials to try and reduce error
intervals = [0,0,0]
for j in range(0,100) :
    (t1, t2, t3, t4, t5, t6) = time_trial()
    intervals[0] += (t2-t1)
    intervals[1] += (t4-t3)
    intervals[2] += (t6-t5)

print "SetValue: %f; InsertNextValue1: %f; InsertNextValue2: %f" %
(intervals[0], intervals[1], intervals[2])



-->VPutz




More information about the vtkusers mailing list