#!/usr/bin/ruby -I. -w

require "benchmark"
require "rexml/document"
require 'rexml/pullparser'
require 'rexml/streamlistener'

include Benchmark

n = 400
bm(20) do |test|
	file = File.new('../documentation.xml')
	test.report('Pull Parsing') { 10.times{ 
		pp = REXML::PullParser.new(file)
		while pp.has_next?
			pp.next
		end
		file.rewind
	}}
	l = "sean"
	l.extend( REXML::StreamListener )
	test.report('Stream Parsing') { 10.times{
		REXML::Document.parse_stream( file, l )
		file.rewind
	}}
	test.report('Big document parsing') { 5.times {
		REXML::Document.new( file )
		file.rewind
	}}
	File.open( "project.xml" ) do |source|
		test.report("parsing file") {
			(n/2).times {
				REXML::Document.new source
				source.rewind
			}
		}
	end
	test.report("Document.new") { n.times { REXML::Document.new }}
	test.report("new element") { n.times { REXML::Element.new }}
	document = REXML::Document.new
	document.add_element "duh"
	test.report("add element") { 
		n.times { document.root.add_element( "tag1", {"blah" => "four"} ) }
	}
	el1 = REXML::Element.new
	test.report("add child") { n.times { 
		el2 = REXML::Element.new
		el1 << el2
	}}
	test.report("Tree manipulation") { n.times {
		doc = REXML::Document.new
		doc.add_element("tag1", {"blah"=>"four"})		# Attributes are optional

		# The following is faster than add_element
		tag2 = REXML::Element.new("tag2")
		tag2.attributes["some"] = "valu"
		doc.root.add_element << tag2						# Same as root.add_element

		tag3 = REXML::Element.new("tag3")
		tag2.elements << tag3
	}}
	File.open( "project.xml" ) do |source|
		document = REXML::Document.new source
	end
	test.report("Writing tree") { n.times {
		string = ""
		document.write string
	}}
	test.report("Detecting children") { n.times {
		element = document.root.detect {|element|
			element.instance_of? REXML::Element and element.name == "Datasets"
		}
		element = element.detect{|element|
			element.instance_of? REXML::Element and 
			element.name == "link" and 
			element.attributes["idref"] == '18'
		}
	}}
	test.report("XPath searching") { (n/2).times {
		element = document.root.elements["Datasets/link[@idref='18']"]
	}}
	GC::start
	doc = REXML::Document.new(File.new("../documentation.xml"))
	test.report("Big document XPath") { 10.times {
		REXML::XPath.first( doc, '//subsection[@title="Unit tests"]' )
	}}
end
