- source files and Makefiles need never be executable - scripts are run directly by their interpreters in the test suites, so also do not need to be executable
67 lines
1.5 KiB
Ruby
67 lines
1.5 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
require 'benchmark'
|
|
require 'li_std_speed'
|
|
include Li_std_speed
|
|
|
|
def benchmark(f, phigh, sequences)
|
|
print f.class
|
|
puts '%10s ' % 'n' + sequences.inject('') { |a,s| a << '%10s' % s.class }
|
|
0.upto(phigh-1) do |p|
|
|
n = 2**p
|
|
print "%10d"%n
|
|
$stdout.flush
|
|
for s in sequences
|
|
cont = s.new((0..n).to_a)
|
|
Benchmark.benchmark { f.call(cont) }
|
|
end
|
|
end
|
|
end
|
|
|
|
def iterate(cont)
|
|
# expected: O(n)
|
|
# got: O(n**2) for set/list (vector/deque fine)
|
|
it = cont.begin
|
|
last = cont.end
|
|
while it != last
|
|
it.next
|
|
end
|
|
end
|
|
|
|
|
|
def erase(cont)
|
|
# expected: O(n)
|
|
# got: O(n**2) for vector/deque and O(n**3) for set/list
|
|
it = cont.end
|
|
# can't reuse begin since it might get invalidated
|
|
while it != cont.begin
|
|
it.previous
|
|
# set returns None, so need to reobtain end
|
|
it = cont.erase(it) or cont.end
|
|
end
|
|
end
|
|
|
|
def insert(cont)
|
|
it = cont.end
|
|
size = cont.size
|
|
if cont.kind_of? RbSet
|
|
# swig stl missing hint version of insert for set
|
|
# expected would be O(n) with iterator hint version
|
|
# expected: O(n*log(n))
|
|
# got: O(n**3*log(n))
|
|
size.upto(size<<1) { |x| cont.insert(x) }
|
|
else
|
|
# expected: O(n)
|
|
# got: O(n**3) for list (vector/deque fine)
|
|
size.upto(size<<1) { |x| cont.push(x) }
|
|
end
|
|
end
|
|
|
|
if $0 == __FILE__
|
|
sequences = [RbVector,RbDeque,RbSet,RbList]
|
|
for f,phigh in [[method(:iterate),15], [method(:insert),15],
|
|
[method(:erase),11]]
|
|
benchmark(f, phigh, sequences)
|
|
end
|
|
end
|
|
|