[CMake] Re: [Swig-user] Performance bug in pycontainers.swg

gga ggarra at advancedsl.com.ar
Fri May 18 18:29:26 EDT 2007


Josh Cherry wrote:
> 1. The slowness depends (in part, at least) on the fact that there is a 
> cont.end() call for every iteration.  If the code is changed to look like 
> this:
> 
>      cont_end = cont.end()
>      while it != cont.end():
>          it.next()
> 
> it is much faster.  Of course, calling end() *should* be constant time.
> 

In C++, maybe, where the compiler may be able to inline the call
completely.  When you bind it to a scripting language, end() is always a
function call.  This slowdown is unavoidable.
Even in C++, the recommendation is NOT to call end() repeatedly if you
can avoid it, as inlining is just a hint and the compiler could fail to
do it (for whatever reason).

> Ondrej Marsalek wrote:
>
>         n   pyvector     pylist    pydeque      pyset
>      1024       1.87      25.19       2.40      19.79

Those numbers don't look that right, but they don't look wrong either to
me.

I should also point out that this:

>   cont = pystl.pylist(xrange(n))

will indeed do a dummy check on each element of the range when *FILLING*
the container, not when iterating thru it.  Again, this check cannot be
avoided.
Take this out of the timing and you'll see the numbers perform much better.

Here's for example the test fixed (for ruby):

--
%module li_std_speed

%include <std_list.i>
%include <std_vector.i>
%include <std_deque.i>
%include <std_set.i>

%template(RbList)   std::list<swig::GC_VALUE>;
%template(RbVector) std::vector<swig::GC_VALUE>;
%template(RbDeque)  std::deque<swig::GC_VALUE>;
%template(RbSet)    std::set<swig::GC_VALUE>;

--

require 'li_std_speed'
include Li_std_speed

require 'benchmark'

def iterate(c)
  i = c.begin
  e = c.end
  while i != e
    i.next
  end
end

n = 16384

elems = (0..n).to_a

puts '--- build containers (takes long)'

all = {}
[RbVector, RbList, RbDeque, RbSet].each do |klass|
  puts "build #{klass}"
  all[klass] = klass.new( elems )
end

puts '--- iterate'

GC.disable # to avoid measuring any GC slowdown
all.each do |klass, c|
  Benchmark.benchmark('') do |x|
    name = klass.to_s.sub(/.*::/,'') + ' '*5
    name = name[0,10]
    x.report("#{name} #{n}") { iterate(c) }
  end
end

Iteration speed is linear on all containers:

--- build containers (takes long)
build Li_std_speed::RbVector
build Li_std_speed::RbList
build Li_std_speed::RbDeque
build Li_std_speed::RbSet
--- iterate
RbList     16384  0.083333   0.000000   0.083333 (  0.052038)
RbDeque    16384  0.116667   0.000000   0.116667 (  0.061717)
RbVector   16384  0.100000   0.000000   0.100000 (  0.061583)
RbSet      16384  0.100000   0.000000   0.100000 (  0.063578)


If, however, assignment is taking into account (this is done with the
container's assign if available), each container behaves quite
differently.


require 'li_std_speed'
include Li_std_speed

require 'benchmark'

n = 16384
@elems = (0..n).to_a

def create_and_iterate(klass)
  c = klass.new( @elems )
  i = c.begin
  e = c.end
  while i != e
    i.next
  end
end

GC.disable # to avoid measuring any GC slowdown
[RbVector, RbList, RbDeque, RbSet].each do |klass|
  Benchmark.benchmark('') do |x|
    name = klass.to_s.sub(/.*::/,'') + ' '*5
    name = name[0,10]
    x.report("#{name} #{n}") { create_and_iterate(klass) }
  end
end
---
RbVector   16384  4.183333   0.033333   4.216667 (  2.550497)
RbList     16384 17.566667   0.016667  17.583333 ( 10.562868)
RbDeque    16384  3.533333   0.000000   3.533333 (  2.118050)
RbSet      16384 17.066667   0.016667  17.083333 ( 10.272435)

*NOTE:  std::set is slow as expected.  std::deque and std::vector are
expected to be relatively fast.
The performance of std::list is weird, as you expect insertions on a
list to be constant time.  Problem is, the list copy constructor is
*not* constant, while a std::vector/deque is (usually just a memcpy).
Currently swig is kind of dumb in how copy constructors are handled in
the STL, as the container is actually copied twice when the element
passed in is not another STL container, but the language's native
list/array container.

Summary: no bug.


-- 
Gonzalo Garramuño
ggarra at advancedsl.com.ar

AMD4400 - ASUS48N-E
GeForce7300GT
Kubuntu Edgy


More information about the CMake mailing list