Iaki Baz Castillo wrote:

> 2009/4/2 Michael Neumann <mneumann / ntecs.de>:
>> I'd figure out what very common headers are and make them freezed
>> constants, like:
>>
>> FROM = "From".freeze
>> TO = "To".freeze
>>
>> and put references to those string "constants" as keys into the Hash. I
>> assume that this will be as fast as symbols when accessing the hash with
>> those constants, as equality testing just needs to tests for object
>> identity (object_id) and not for the equality of the content.
>>
>> headers = {}
>> headers[FROM] = "alice@qweeq"
>> headers[TO] = "bob@qweqwe"
> 
> Very interesting solution, but I would have some issues with it:
> 
> a) I receive a request with various headers, most of them are well
> kwnown but others can be custom.
> When I extract the header name (after parsing) I get "From" and
> "Custom-Header" strings, and I need to check if these strings belongs
> to well known headers or not before storing them as FROM and
> "Custom-Header". Wouldn't this check be inneficient?

No!

time ruby -e "s,t='a'*100,'a'*100;1_000_000.times{s==t}"
0.567u 0.000s 0:00.58 96.5%     5+1563k 0+0io 0pf+0w

Comparing 1 million strings of size 100 is just half a second in the worst 
case (of which around the half is just method calling overhead!).

If you take more reasonable sized strings (15 characters):

time ruby -e "s,t='a'*15,'a'*15;1_000_000.times{s==t}"
0.326u 0.007s 0:00.33 96.9%     5+1588k 0+0io 0pf+0w

Compared against object id comparison (notice "s == s"):

time ruby -e "s,t='a'*15,'a'*15;1_000_000.times{s==s}"
0.265u 0.000s 0:00.26 100.0%    5+1595k 0+0io 0pf+0w

So, I wouldn't call Ruby strings inefficient. Not the lookup is in general 
the problem with performance, but the memory allocation. Even if string 
comparison is wc. O(n), a key lookup of a hash is in general O(1) regardless
of strings or symbols as keys (especially as the length of the keys is 
usually limited). 

I don't think that this lookup will be significant. If it is significant 
then you're probably using the wrong language :). 
 
> b) Some wellk wnown headers have a name like "Record-Route". The "-"
> symbol is of course dissallowed as Ruby Constant. Using Symbols I can
> use it as :"record-route".

I didn't meant constants, but "constant", i.e. frozen, values. 

  FROM = 'From'.freeze
  RECORD_ROUTE = 'Record-Route'.freeze

  KNOWN_HEADERS = {
    FROM => FROM,
    RECORD_ROUTE => RECORD_ROUTE
  }

  headers = {}
  for key, value in h
    headers[ KNOWN_HEADERS[key] || key ] = value
  end

Regards,

  Michael