several performance optimizations

This commit is contained in:
blackhedd 2006-09-02 13:49:12 +00:00
parent 58f5db9716
commit 6a371b988d

View file

@ -38,6 +38,20 @@ module Net
class BerError < Exception; end class BerError < Exception; end
class BerIdentifiedString < String
attr_accessor :ber_identifier
def initialize args
super args
end
end
class BerIdentifiedArray < Array
attr_accessor :ber_identifier
def initialize
super
end
end
# This module is for mixing into IO and IO-like objects. # This module is for mixing into IO and IO-like objects.
module BERParser module BERParser
@ -80,7 +94,10 @@ module Net
lengthlength,contentlength = if n <= 127 lengthlength,contentlength = if n <= 127
[1,n] [1,n]
else else
j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc} # Replaced the inject because it profiles hot.
#j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
j = 0
(n & 127).times {j = (j << 8) + getc}
[1 + (n & 127), j] [1 + (n & 127), j]
end end
@ -120,16 +137,20 @@ module Net
end end
=end =end
obj = if objtype == :boolean # == is expensive so sort this if/else so the common cases are at the top.
newobj != "\000" obj = if objtype == :string
elsif objtype == :string #(newobj || "").dup
(newobj || "").dup s = BerIdentifiedString.new( newobj || "" )
s.ber_identifier = id
s
elsif objtype == :integer elsif objtype == :integer
j = 0 j = 0
newobj.each_byte {|b| j = (j << 8) + b} newobj.each_byte {|b| j = (j << 8) + b}
j j
elsif objtype == :array elsif objtype == :array
seq = [] #seq = []
seq = BerIdentifiedArray.new
seq.ber_identifier = id
sio = StringIO.new( newobj || "" ) sio = StringIO.new( newobj || "" )
# Interpret the subobject, but note how the loop # Interpret the subobject, but note how the loop
# is built: nil ends the loop, but false (a valid # is built: nil ends the loop, but false (a valid
@ -138,13 +159,17 @@ module Net
seq << e seq << e
end end
seq seq
elsif objtype == :boolean
newobj != "\000"
else else
raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" ) raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
end end
# Add the identifier bits into the object if it's a String or an Array. # Add the identifier bits into the object if it's a String or an Array.
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway. # We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end" # Replaced this mechanism with subclasses because the instance_eval profiled too hot.
#obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
#obj.ber_identifier = id if obj.respond_to?(:ber_identifier)
obj obj
end end