Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^4: PerlApi: hashes

by BrowserUk (Patriarch)
on Aug 12, 2015 at 12:38 UTC ( [id://1138311]=note: print w/replies, xml ) Need Help??


in reply to Re^3: PerlApi: hashes
in thread PerlApi: hashes

hello? https://metacpan.org/pod/Hash::Util#hash_value

Nice find! But, it doesn't help :(

I can use the PERL_HASH macro to obtain the hash value; but even if I set up an SV with the key for hv_exists_ent() to ignore; it complains: Use of uninitialized value in subroutine entry; for every iteration; and apparently does nothing?

HV* countColors( SV *img ) { STRLEN l; U32 *rgba = (U32*)SvPVx( img, l ), i; HV* counts = newHV(); SV *dummy = newSV( 4 ); l /= 4; for( i = 0; i < l; ++i ) { U32 hash; PERL_HASH( (U32)hash, (char*)&rgba[ i ], 4 ); SvPV_set( dummy, (char*)&rgba[ i ] ); if( hv_exists_ent( counts, dummy, hash ) ) { SV **val = hv_fetch( counts, (char*)&rgba[ i ], 4, hash ); SvIV_set( *val, SvIV( *val ) + 1 ); } else { SV *val = newSViv( 1 ); hv_store( counts, (char*)&rgba[ i ], 4, val, hash ); } } return counts; }

Even if I could work out (why do I have to guess? Why isn't this stuff documented?) how to persuade hv_exists_ent() to use the pre-calculated hash value and ignore the SV it requires, setting that SV up costs more than recalculating the hash does -- which is what I was trying to avoid.

What a dumb api.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
In the absence of evidence, opinion is indistinguishable from prejudice.
I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!

Replies are listed 'Best First'.
Re^5: PerlApi: hashes
by NERDVANA (Deacon) on Jul 11, 2018 at 04:02 UTC

    Running into a similar deal, so I figured I'd share what I learned here.

    First, you can't ever insert into a hash with only the hash value - you need the original string so that the hash implementation can do the final official comparison.

    Next, while needing a SV is annoying, it's also related to performance. Perl has an internal pool of constants, and can make SVs from them. If your hash is using those as keys, and you perform the lookup using one, then the hash can skip the strncmp() and just compare the pointers. This is a lot like Java's String.intern(). I would presume that any time you use a literal key in your perl code, Perl probably adds that to the global pool and then hash get/set using those compiled scalars gets a lot faster. You can allocate one of these scalars with newSVpvn_share, if it is appropriate to do so. (obviously it would be bad to pollute the global string table with keys that come from transient data)

    This doesn't solve the problem of wanting to have a more optimized way of fetching/storing a char* with a known hash, though. Looks like it's possible with the underlying implementation, but I haven't found any official API for it.

    ----- UPDATE -----

    Looks like the authors of Class::XSAccessor had the same desire, so they just wrote new wrappers around hv_common_key_len. Of course it's probably a bad idea to reach that deep into perl for casual downstream modules, but the interesting bits can be found at: https://metacpan.org/source/SMUELLER/Class-XSAccessor-1.19/XS/Hash.xs

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2024-03-28 09:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found