Iñaki Baz Castillo said:
2009/4/2 Michael Neumann said:
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