From: Michael Neumann Date: 2009-04-02T20:08:15+09:00 Subject: Re: Symbols garbage collector in Ruby1.9, fixed? I単aki Baz Castillo wrote: > 2009/4/2 Michael Neumann : >> 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