base = File.dirname(__FILE__) $LOAD_PATH.unshift(File.expand_path(base)) $LOAD_PATH.unshift(File.expand_path(File.join(base, "..", "lib"))) require "active_ldap" require "benchmark" include ActiveLdap::GetTextSupport argv = ARGV.dup unless argv.include?("--config") argv.unshift("--config", File.join(base, "config.yaml")) end argv, opts, options = ActiveLdap::Command.parse_options(argv) do |opts, options| options.prefix = "ou=People" opts.on("--prefix=PREFIX", _("Specify prefix for benchmarking"), _("(default: %s)") % options.prefix) do |prefix| options.prefix = prefix end end ActiveLdap::Base.setup_connection config = ActiveLdap::Base.configuration LDAP_HOST = config[:host] LDAP_METHOD = config[:method] if LDAP_METHOD == :ssl LDAP_PORT = config[:port] || URI::LDAPS::DEFAULT_PORT else LDAP_PORT = config[:port] || URI::LDAP::DEFAULT_PORT end LDAP_BASE = config[:base] LDAP_PREFIX = options.prefix LDAP_USER = config[:bind_dn] LDAP_PASSWORD = config[:password] class ALUser < ActiveLdap::Base ldap_mapping :dn_attribute => 'uid', :prefix => LDAP_PREFIX, :classes => ['posixAccount', 'person'] end class ALUserLdap < ALUser end ALUserLdap.setup_connection(config.merge(:adapter => "ldap")) class ALUserNetLdap < ALUser end ALUserNetLdap.setup_connection(config.merge(:adapter => "net-ldap")) def search_al_ldap count = 0 ALUserLdap.find(:all).each do |e| count += 1 end count end def search_al_net_ldap count = 0 ALUserNetLdap.find(:all).each do |e| count += 1 end count end def search_al_ldap_without_object_creation count = 0 ALUserLdap.search.each do |e| count += 1 end count end def search_al_net_ldap_without_object_creation count = 0 ALUserNetLdap.search.each do |e| count += 1 end count end # === search_ldap # def search_ldap(conn) count = 0 conn.search("#{LDAP_PREFIX},#{LDAP_BASE}", LDAP::LDAP_SCOPE_SUBTREE, "(uid=*)") do |e| count += 1 end count end # -- search_ldap def search_net_ldap(conn) count = 0 conn.search(:base => "#{LDAP_PREFIX},#{LDAP_BASE}", :scope => Net::LDAP::SearchScope_WholeSubtree, :filter => "(uid=*)") do |e| count += 1 end count end def ldap_connection require 'ldap' if LDAP_METHOD == :tls conn = LDAP::SSLConn.new(LDAP_HOST, LDAP_PORT, true) else conn = LDAP::Conn.new(LDAP_HOST, LDAP_PORT) end conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3) conn.bind(LDAP_USER, LDAP_PASSWORD) if LDAP_USER and LDAP_PASSWORD conn rescue LoadError nil end def net_ldap_connection require 'net/ldap' net_ldap_conn = Net::LDAP::Connection.new(:host => LDAP_HOST, :port => LDAP_PORT) if LDAP_USER and LDAP_PASSWORD net_ldap_conn.setup_encryption(:method => :start_tls) if LDAP_METHOD == :tls net_ldap_conn.bind(:method => :simple, :username => LDAP_USER, :password => LDAP_PASSWORD) end net_ldap_conn rescue LoadError nil end def populate_base ActiveLdap::Populate.ensure_base if ActiveLdap::Base.search.empty? raise "Can't populate #{ActiveLdap::Base.base}" end end def populate_users ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping :dn_attribute => "ou", :prefix => "", :classes => ["top", "organizationalUnit"] ou_class.new(LDAP_PREFIX.split(/=/)[1]).save! 100.times do |i| name = i.to_s user = ALUser.new(name) user.uid_number = 100000 + i user.gid_number = 100000 + i user.cn = name user.sn = name user.home_directory = "/nonexistent" user.save! end end def populate populate_base populate_users end # === main # def main(do_populate) if do_populate puts(_("Populating...")) dumped_data = ActiveLdap::Base.dump(:scope => :sub) ActiveLdap::Base.delete_all(nil, :scope => :sub) populate puts end # Standard connection # ldap_conn = ldap_connection net_ldap_conn = net_ldap_connection al_ldap_count = 0 al_net_ldap_count = 0 al_ldap_count_without_object_creation = 0 al_net_ldap_count_without_object_creation = 0 ldap_count = 0 net_ldap_count = 0 Benchmark.bmbm(20) do |x| [1].each do |n| GC.start x.report("%3dx: AL(LDAP)" % n) do n.times {al_ldap_count = search_al_ldap} end GC.start x.report("%3dx: AL(Net::LDAP)" % n) do n.times {al_net_ldap_count = search_al_net_ldap} end GC.start x.report("%3dx: AL(LDAP: No Obj)" % n) do n.times do al_ldap_count_without_object_creation = search_al_ldap_without_object_creation end end x.report("%3dx: AL(Net::LDAP: No Obj)" % n) do n.times do al_net_ldap_count_without_object_creation = search_al_net_ldap_without_object_creation end end GC.start if ldap_conn x.report("%3dx: LDAP" % n) do n.times {ldap_count = search_ldap(ldap_conn)} end end GC.start if net_ldap_conn x.report("%3dx: Net::LDAP" % n) do n.times {net_ldap_count = search_net_ldap(net_ldap_conn)} end end end end puts puts(_("Entries processed by Ruby/ActiveLdap + LDAP: %d") % al_ldap_count) puts(_("Entries processed by Ruby/ActiveLdap + Net::LDAP: %d") % \ al_net_ldap_count) puts(_("Entries processed by Ruby/ActiveLdap + LDAP: " \ "(without object creation): %d") % \ al_ldap_count_without_object_creation) puts(_("Entries processed by Ruby/ActiveLdap + Net::LDAP: " \ "(without object creation): %d") % \ al_net_ldap_count_without_object_creation) puts(_("Entries processed by Ruby/LDAP: %d") % ldap_count) puts(_("Entries processed by Net::LDAP: %d") % net_ldap_count) ensure if do_populate puts puts(_("Cleaning...")) ActiveLdap::Base.delete_all(nil, :scope => :sub) ActiveLdap::Base.load(dumped_data) end end main(LDAP_USER && LDAP_PASSWORD)