Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^2: Concerning hash operations (appending, concatenating)

by thor (Priest)
on Mar 24, 2005 at 16:57 UTC ( [id://442118]=note: print w/replies, xml ) Need Help??


in reply to Re: Concerning hash operations (appending, concatenating)
in thread Concerning hash operations (appending, concatenating)

This is actually really, really useful. People often ask the question "how do I store a value in a hash only if it's a new value?". Here's the answer.

thor

Feel the white light, the light within
Be your own disciple, fan the sparks of will
For all of us waiting, your kingdom will come

Replies are listed 'Best First'.
Re^3: Concerning hash operations (appending, concatenating)
by japhy (Canon) on Mar 24, 2005 at 17:50 UTC
    Yeah, but I don't like it. I don't like assigning X to itself like the example does. I'd prefer a slightly long-winded approach:
    $hash{$_} = $otherhash{$_} for grep !exists $hash{$_}, keys %otherhash +;
    Or:
    { my @new_keys = grep !exists $hash{$_}, keys %otherhash; @hash{@new_keys} = @otherhash{@new_keys}; }
    _____________________________________________________
    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      But isn't that creating arrays and going through loops that are unnecessary?
      --------------
      "But what of all those sweet words you spoke in private?"
      "Oh that's just what we call pillow talk, baby, that's all."
        Here's my benchmark:
        use Benchmark 'cmpthese'; use strict; my %hash = 1 .. 10_000; my %add = 9_001 .. 11_000; cmpthese(-5, { BASE => sub { my %copy = %hash; }, JAPHY => sub { my %copy = %hash; my @new = grep !exists $copy{$_}, keys %add; @copy{@new} = @add{@new}; }, ZAXO => sub { my %copy = %hash; %copy = (%add, %copy); }, NULL => sub { my %copy = %hash; %copy = (%copy); }, });
        Here are the results I get:
        Rate ZAXO NULL JAPHY BASE ZAXO 15.1/s -- -22% -61% -76% NULL 19.3/s 28% -- -50% -69% JAPHY 38.9/s 157% 101% -- -38% BASE 62.4/s 312% 223% 60% --
        The two cases 'BASE' and 'NULL' show that Perl does not optimize %hash = %hash at all, since 'NULL' is three times slower than 'BASE'. 'JAPHY' is 2.5 times faster than 'ZAXO' in this run, with 500 old keys and 500 new keys. When I change %add to be (5_001 .. 12_000), the run times are:
        Rate ZAXO NULL JAPHY BASE ZAXO 11.4/s -- -39% -58% -81% NULL 18.6/s 63% -- -31% -69% JAPHY 26.9/s 136% 45% -- -56% BASE 60.5/s 431% 225% 125% --
        The point is that %a = (%b, %a) is slow because it is O(N+M) where N is the size of %a and M is the size of %b. My code is O(M) -- specifically, O(M(1+x)) where x is the fraction of keys in %b that aren't in %a -- because it doesn't iterate over %a at all, only %b.
        _____________________________________________________
        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://442118]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-03-29 14:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found