Symbols garbage collector in Ruby1.9, fixed?

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

2009/4/2 Rick DeNatale said:
Actually, I'm pretty sure that Symbols are faster as hash keys because
Hash#=3D=3D is O(1) while String#=3D=3D is O(n) where n is the length of = the string.
That said, the HashWithIndifferentAccess class in activesupport =C2=A0all= ows
either strings or symbols to be used interchangeably as the key argument = in
methods like [] and []=3D, but it always USES the string form as the key.

Oh, then it's better just to use strings, I don't need to support
string and symbols at the same time, I just need to make a decission.

Thanks for pointing it out.



--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 
I

Iñaki Baz Castillo

2009/4/2 Michael Neumann said:
I'd figure out what very common headers are and make them freezed constan= ts,
like:

=C2=A0FROM =3D "From".freeze
=C2=A0TO =3D "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 ident= ity
(object_id) and not for the equality of the content.

=C2=A0headers =3D {}
=C2=A0headers[FROM] =3D "alice@qweeq"
=C2=A0headers[TO] =3D "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?

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".

Well, I have to think about it. Thanks a lot for all the received help. Reg=
ards.


Btw, this is the approach that for example Mongrel uses.

Then I must investigate how it handles case b).


--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 
M

Michael Neumann

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
 
I

Iñaki Baz Castillo

2009/4/2 Michael Neumann said:
=C2=A0FROM =3D 'From'.freeze
=C2=A0RECORD_ROUTE =3D 'Record-Route'.freeze

=C2=A0KNOWN_HEADERS =3D {
=C2=A0 =C2=A0FROM =3D> FROM,
=C2=A0 =C2=A0RECORD_ROUTE =3D> RECORD_ROUTE
=C2=A0}

=C2=A0headers =3D {}
=C2=A0for key, value in h
=C2=A0 =C2=A0headers[ KNOWN_HEADERS[key] || key ] =3D value
=C2=A0end

This seems a wonderful solution :)

Thanks a lot.


--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,232
Latest member
DorotheaDo

Latest Threads

Top