Q: efficient string copy without using refs 
Author Message
 Q: efficient string copy without using refs

I am thinking about how to copy a large scalar data value efficiently into
a hash (i.e. with minimal extra memory usage).  One way is to use a ref to
the large string , but I would like to access the value later as a simple
scalar, not as a ref.

An example (this code is just to illustrate what I mean)

        my %hash;

        if (my ($item1,$item2) = m/(item1_re)(large_data_re)/ )
        {  # item 2 is big
           my $key=some_function_of($item1);
           $hash{$key}=$item2;  # but I don't want to make a copy of
                                # item2.
        }

I could use
                $hash{$item1}= \$item2;

but then I always have to remember to deref the item later, which is not a
real big deal, except that it makes this one hash an exception to
virtually all the others, so its easy to forget.

I seems like there should be some way to make the hash at that key "take
over" the ownership of the string item2.  If this was a simple variable
(and also not a my) then I think I could say *var2 = \$item2, but the
value has to go into a hash, and its usually a my variable to boot.

Suggestions on the best (any?) ways to do this would be appreciated.



Wed, 19 Feb 2003 09:17:20 GMT  
 Q: efficient string copy without using refs


Quote:
>I seems like there should be some way to make the hash at that key "take
>over" the ownership of the string item2.  If this was a simple variable
>(and also not a my) then I think I could say *var2 = \$item2, but the
>value has to go into a hash, and its usually a my variable to boot.

tie the hash so that it automatically dereferences values that are refs?

--
Peter Scott



Thu, 20 Feb 2003 00:56:17 GMT  
 Q: efficient string copy without using refs

Quote:

> I am thinking about how to copy a large scalar data value efficiently into
> a hash (i.e. with minimal extra memory usage).  One way is to use a ref to
> the large string , but I would like to access the value later as a simple
> scalar, not as a ref.

> An example (this code is just to illustrate what I mean)

>    my %hash;

>    if (my ($item1,$item2) = m/(item1_re)(large_data_re)/ )
>    {  # item 2 is big
>       my $key=some_function_of($item1);
>       $hash{$key}=$item2;  # but I don't want to make a copy of
>                            # item2.
>    }

> I could use
>            $hash{$item1}= \$item2;

> but then I always have to remember to deref the item later, which is not a
> real big deal, except that it makes this one hash an exception to
> virtually all the others, so its easy to forget.

> I seems like there should be some way to make the hash at that key "take
> over" the ownership of the string item2.  If this was a simple variable
> (and also not a my) then I think I could say *var2 = \$item2, but the
> value has to go into a hash, and its usually a my variable to boot.

> Suggestions on the best (any?) ways to do this would be appreciated.

You can use ties:

package DerefHash;
use Tie::Hash;
use base qw(Tie::StdHash);

sub FETCH {

    ${$self->{$key}};

Quote:
}

package main;

tie %x, 'DerefHash';

$x{Foo} = \"abcdef";
warn $x{Foo};
__END__

Maybe some other tie methods (FIRSTKEY, NEXTKEY and such) need
overriding too.

Regards
        Slaven

--
use Tk;$c=tkinit->Canvas(-he,20)->grid;$x=5;map{s!\n!!g;map{create$c 'line'=>
map{$a=-43+ord;($x+($a>>3)*2=>5+($a&7)*2)}split''}split"!";$x+=12}split/_/=>'K
PI1_+09IPK_K;-OA1_+K!;A__1;Q!7G_1+QK_3CLPI90,_+K!;A_+1!KQ!.N_K+1Q!.F_1+KN.Q__1+
KN._K+1Q!.F_1+KN.Q_+1Q__+1!KQ!.N_1;Q!7G_K3,09Q_+1!K.Q_K+1Q!.F_1+KN.Q_';MainLoop



Wed, 19 Feb 2003 21:42:57 GMT  
 Q: efficient string copy without using refs

(Hello Peter, and how's the weather on the coast?)

Quote:

> [This is a courtesy copy of a message which was also posted to the
>  newsgroup(s) shown in the header.]



> >I seems like there should be some way to make the hash at that key "take
> >over" the ownership of the string item2.  If this was a simple variable
> >(and also not a my) then I think I could say *var2 = \$item2, but the
> >value has to go into a hash, and its usually a my variable to boot.

> tie the hash so that it automatically dereferences values that are refs?

My concern with tieing is that at some point a fetch has to be used,
and the fetch has to return a real value (not a ref since this is the
whole point of the tie) and so the fetch has to have code such as

        return $$the_saved_ref;

I worry that this makes a copy, which is what I want to avoid.  If this is
true then the tie will have simply postponed the copy.  However, it's not
clear to me how to test whether a copy is being made when something like

        $hash{'this_entry_is_a_tied_ref_to_string'} =~ m/xyz/;

is run.  I wonder if the same thing would happen with

        ${$hash{'this_key_returns_a_ref'}} =~ m/xyz/;

Does the m// run against the original value of the string, or does the
de-ref make a copy?  and (short of digging through the perl source code)
how to know for sure?

Anyway, Larry Rosler (sp? - and thanks) has suggested the real answer
which is just to redo my code slightly (and why didn't I think of that -
duh!).

malcolm



Mon, 24 Feb 2003 03:08:01 GMT  
 Q: efficient string copy without using refs


Quote:

>(Hello Peter, and how's the weather on the coast?)

Shower just passed over.  It should hit you by the time this makes it to your server :-)

Quote:

>> [This is a courtesy copy of a message which was also posted to the
>>  newsgroup(s) shown in the header.]



>> >I seems like there should be some way to make the hash at that key "take
>> >over" the ownership of the string item2.  If this was a simple variable
>> >(and also not a my) then I think I could say *var2 = \$item2, but the
>> >value has to go into a hash, and its usually a my variable to boot.

>> tie the hash so that it automatically dereferences values that are refs?

>My concern with tieing is that at some point a fetch has to be used,
>and the fetch has to return a real value (not a ref since this is the
>whole point of the tie) and so the fetch has to have code such as

>        return $$the_saved_ref;

>I worry that this makes a copy, which is what I want to avoid.  If this is
>true then the tie will have simply postponed the copy.  However, it's not
>clear to me how to test whether a copy is being made when something like

>    $hash{'this_entry_is_a_tied_ref_to_string'} =~ m/xyz/;

>is run.  I wonder if the same thing would happen with

>    ${$hash{'this_key_returns_a_ref'}} =~ m/xyz/;

>Does the m// run against the original value of the string, or does the
>de-ref make a copy?  and (short of digging through the perl source code)
>how to know for sure?

I think this is fairly conclusive:

#!/usr/bin/perl -wl
package DerefHash;
use Tie::Hash;
use base qw(Tie::StdHash);

sub FETCH {

    ${$self->{$key}};

Quote:
}

package main;
sub procsize { (split /\s+/, (`ps -lp $$`)[1])[9] }
tie %x, 'DerefHash';

print "Before creation: ", procsize;
my $large_string = join '', map chr rand 255, 1..1_000_000;
print "Before assignment: ", procsize;
$x{Foo} = \$large_string;
print "Before length: ", procsize;
print length $x{Foo};
print "Before match: ", procsize;
$x{Foo} =~ /abc/;
print "Before deref and match: ", procsize;
$foo = \$large_string;
${$foo} =~ /abc/;
print "Before copy: ", procsize;
$y = $x{Foo};
print "Final size: ", procsize;
__END__

Before creation: 11742
Before assignment: 19091
Before length: 19091
1000000
Before match: 19091
Before deref and match: 19091
Before copy: 19091
Final size: 19336

--
Peter Scott



Tue, 25 Feb 2003 06:02:49 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. HELP! 2 bde application using the same database

2. TFileStream.Create >>> Limit size???

3. efficient string copy without using refs

4. s// using lexicals and refs in an eval'ed string

5. Detach dBase Index without DBD ?

6. Array refs without temp-vars and strange behaviour of my

7. Using File::Copy and Sockets to copy public files from http addresses

8. Warning using copy from File::Copy

9. Binary -font file for Pascal

10. DBGrid: How do I make a sum, of all the numbers occuring in a column?

11. help: push array refs into hash, sort by refs in hash

12. strings and symbol refs and strict - oh my!

 

 
Powered by phpBB® Forum Software