# Net::LDAP vs ruby/ldap

**URL:** <https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120>\
**Category:** Ruby\
**Created:** [April 27, 2007, 9:10pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120 "2007-04-27T21:10:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dacat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/779978/32.png) [@dacat](https://www.ruby-forum.com/u/dacat)\
**Post date:** [April 27, 2007, 9:10pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120/1 "2007-04-27T21:10:51Z")

</div>

The basic premise of this test was to see how long it would take to do  
the following:

1000 Basic lookups on a known attribute/value pair over an unencrypted  
connection using anonymous bind for each library.

This post is for informational purposes, I knew the NET::LDAP lib  
would be slower but I wanted to see by how much.  
{if you are new to ruby, the reason it is slower is because its a TRUE  
ruby implementation of the LDAP rfc. while on the other hand the ruby/  
ldap lib is a C front end to the openldap library}

## Bottom line is – I just figured i would share. Code:

require ‘benchmark’  
include Benchmark

LOOP\_COUNT = 1000  
require ‘ldap’  
require ‘net/ldap’

HOST = ‘[somehost.com](http://somehost.com)’  
S\_ATTR = ‘some attribute that exists that can be lookedup’  
S\_VAL = ‘a value for the attribute that iss valid’  
TREE\_BASE = ‘a valid base ex. o=com’

class LdapTest

def net\_ldap\_test  
ldap = Net::LDAP.new :host =\> HOST, :port =\> 389  
filter = Net::LDAP::Filter.eq( S\_ATTR, S\_VAL )  
ldap.search( :base =\>TREE\_BASE, :filter =\> filter ) do |entry|  
a=entry.dn  
end  
nil  
end

def ldap\_test  
conn = LDAP::Conn.new(HOST, LDAP::LDAP\_PORT)  
filter = “(#{S\_ATTR}=#{S\_VAL})”  
conn.search(TREE\_BASE, LDAP::LDAP\_SCOPE\_SUBTREE, filter) do |entry|  
a=entry.dn  
end  
nil  
end

ldap\_test=LdapTest.new

# Benchmark.bm(15) do |x| x.report(“NET::LDAP:”) { for i in 1…LOOP\_COUNT; ldap\_test.net\_ldap\_test; end } x.report(“ruby-ldap”) { for i in 1…LOOP\_COUNT ; ldap\_test.ldap\_test; end } end end

My results.  
user system total real  
NET::LDAP: 7.150000 0.580000 7.730000 ( 19.494588)  
ruby-ldap 0.210000 0.120000 0.330000 ( 11.853484)

ruby/ldap : [http://ruby-ldap.sourceforge.net/](http://ruby-ldap.sourceforge.net/)  
net::ldap : [http://rubyforge.org/projects/net-ldap/](http://rubyforge.org/projects/net-ldap/)

ruby --version  
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]

---

<div class="post-metadata">

**Author:** ![dacat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/779978/32.png) [@dacat](https://www.ruby-forum.com/u/dacat)\
**Post date:** [April 27, 2007, 9:30pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120/2 "2007-04-27T21:30:53Z")

</div>

On Apr 27, 1:07 pm, dacat [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ldap lib is a C front end to the openldap library}
> 
> ldap.search( :base =\>TREE\_BASE, :filter =\> filter ) do |entry|  
> end  
> end
> 
> ruby --version  
> ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]

While it’s interesting, I’m afraid I have to stick with net-ldap. The  
problem with ruby-ldap is that it segfaults in conjunction with  
WEBrick, as I know all too well.

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![dacat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/779978/32.png) [@dacat](https://www.ruby-forum.com/u/dacat)\
**Post date:** [April 27, 2007, 10:21pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120/3 "2007-04-27T22:21:19Z")

</div>

On Sat, 28 Apr 2007, Daniel B. wrote:

> > ruby implementation of the LDAP rfc. while on the other hand the ruby/  
> > require ‘net/ldap’  
> > filter = Net::LDAP::Filter.eq( S\_ATTR, S\_VAL )  
> > a=entry.dn  
> > ldap\_test.ldap\_test; end }  
> > net::ldap :[http://rubyforge.org/projects/net-ldap/](http://rubyforge.org/projects/net-ldap/)  
> > Dan  
> > my good friend justin crawford works heavily with ruby and ldap for the  
> > universtiy of colorado managing a huge federated authentication system.  
> > they  
> > use the pure ruby ldap lib because the c version is unstable. he’s been  
> > using  
> > it for several years on a system that’s serving ~ 100,000 people - so i  
> > think  
> > it’s fast enough.

fyi.

-a

---

<div class="post-metadata">

**Author:** ![dacat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/779978/32.png) [@dacat](https://www.ruby-forum.com/u/dacat)\
**Post date:** [April 27, 2007, 10:27pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120/4 "2007-04-27T22:27:19Z")

</div>

On 4/27/07, dacat [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ruby implementation of the LDAP rfc. while on the other hand the ruby/  
> ldap lib is a C front end to the openldap library}

I’m not entirely sure how to interpret your reported benchmark since the  
system and user times are so different for the two libraries. (I don’t  
know  
how benchmark reports time spent inside liblber and libldap or how it  
measured time spent waiting for the network.) If I may assume that the  
“real” column gives the amount of elapsed wall time for the two tests,  
then  
I’ll say these results (a ratio of about 1.7) more or less square with  
my  
expectations. On a test like this, the pure-Ruby library should take  
between  
1.4 and 1.6 times as long to complete. (Before an extensive optimization  
I  
did several months ago, I would have expected three times longer or  
more.) I  
repeated your test and I got roughly 1.4.

I then modified your test to use Net::LDAP#open rather than  
Net::LDAP#new.  
Somewhat in the manner of File#open, Net::LDAP#open makes a network  
connection, binds, and then performs all ldap operations within a block  
on  
the same connection. Doing the test this way, the pure-Ruby library took  
about half as much time as before. (This squares with expectations since  
I’m  
using an encrypted link to the LDAP server and the network activity is  
an  
important part of the runtime profile.)

The performance tradeoff between pure-Ruby and compiled C code is of  
course  
real, and will be compelling for some applications. In general, the  
reasons  
to prefer the pure-Ruby are the same as ever: no installation of client  
libraries, better platform independence, somewhat better conformance  
with  
the RFCs (for example, as regards LDIF handling), and fully-documented  
handling of the network. (libldap is known for hiding the underlying  
socket  
descriptors and doing unexpected things with them, leading to resource  
leaks  
and other bizarre bugs.)

I recently completed work on a Ruby-scriptable LDAP server, built on  
Net::LDAP and the EventMachine library. This project is intended for  
enterprise use as a caching proxy for an A/D global catalog. So far  
performance has not been a problem.

I’ve also used Net::LDAP in an identity-aggregator for a large  
enterprise,  
simultaneously querying and aggregating results from a large number of  
LDAP  
directories. In this application, performance _was_ a problem,  
especially  
compared to ldapsearch (which uses libldap). Careful tuning of Net::LDAP  
made the performance acceptable, but it was still noticeably less.  
However  
we went with the pure-Ruby version because it was easier to script, and  
actually quite a bit less buggy, especially with coded binary data.

---

<div class="post-metadata">

**Author:** ![dacat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/779978/32.png) [@dacat](https://www.ruby-forum.com/u/dacat)\
**Post date:** [May 18, 2007, 12:30pm UTC](https://www.ruby-forum.com/t/net-ldap-vs-ruby-ldap/93120/5 "2007-05-18T12:30:57Z")

</div>

On Apr 27, 10:16 pm, removed\_email\_address@domain.invalid wrote:

> my good friend justin crawford works heavily with ruby and ldap for the  
> universtiy of colorado managing a huge federated authentication system. they  
> use the pure ruby ldap lib because the c version is unstable. he’s been using  
> it for several years on a system that’s serving ~ 100,000 people - so i think  
> it’s fast enough.

I’d be interested to discover exactly what “unstable” means here, so  
that I can fix the problem.

I’d also like to see code that can reproduce the segfault in  
combination with WEBRick.

Thanks,

Ian
