The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
NAME
    Test::ZeroCopy - Test that two strings share the same memory

SYNOPSIS
        use Test::ZeroCopy;

        is_zerocopy($str1, $str2);
        isnt_zerocopy($str3, $str4);

BACKGROUND
    In applications that attempt to handle large strings efficiently, it can
    often be a huge win to avoid copying strings.

    However, unless you are super careful, it's easy to write perl code that
    copies strings without realising it:

        my $str = "long string goes here";

        sub getstring {
          my $arg = shift; # this is a copy
          return $arg;
        }

        my $ret = getstring($str); # this is another copy

    One solution is to pass references to the string around. Another is to
    use Data::Alias.

    Unfortunately, neither of these approaches help when you want to take a
    substring of the large string: "substr" always copies the contents of
    the string. In C we could avoid copying and instead pass around pointers
    that point into the string.

    Although perl doesn't directly support pointers, it is still possible to
    take a zero-copy substring by creating a scalar with a "SvPV" pointing
    into the large string and a "SvLEN" set to 0 to indicate that the memory
    is "owned" by the large string. Also, the reference counts of the two
    strings are linked so that the large buffer will only be reclaimed once
    all substrings go out of scope.

    String::Slice is an example of a module that can create zero-copy
    sub-strings or "slices" in this way.

    This module came about because I got tired of sprinkling Devel::Peek
    "Dump" statements around my code to confirm no copying occurred. Here is
    an example of how to do that:

        use String::Slice;
        use Devel::Peek;

        my $buf = "ABCDEF";
        my $slice = "";
        slice($slice, $buf, 1, 3);

        Dump($buf);
        Dump($slice);

    And the (abridged) output:

        SV = PV(0x14e0c20) at 0x1501270
          PV = 0x14fa1f0 "ABCDEF"\0
          CUR = 6
          LEN = 16
        SV = PVMG(0x1528db0) at 0x150d678
          PV = 0x14fa1f1 "BCD"
          CUR = 3
          LEN = 0

    Notice how the PV values point into the same buffer.

    Instead of manual inspection, this module lets you add these assertions
    to your test-suites to ensure that you (or future maintainers) don't
    accidentally add wasteful copy operations.

USAGE
    This module provides two Test::More-compatible testing functions:
    "is_zerocopy" and "isnt_zerocopy".

    Each of these functions should be passed two strings. "is_zerocopy" will
    assert that the backing memory is shared between the two strings. This
    is assumed to be the case when any portions of their PV buffers overlap.

    The backing memory is trivially shared in the case where the two strings
    are the same (ie "is_zerocopy($str, $str)"), but is much more
    interesting when one is a substring or "slice" of the other and they
    happen to use the same backing memory (see above).

    "isnt_zerocopy" is the opposite and it will assert that the backing
    memory is *not* shared between the two strings.

    You can also use this module to get the PV address from a perl program
    (which I couldn't figure out how to do with B):

        require Test::ZeroCopy;
        my $addr = Test::ZeroCopy::get_pv_address($string);

SEE ALSO
    Test-ZeroCopy github repo <https://github.com/hoytech/Test-ZeroCopy>

    Data::Alias - Sometimes more convenient to use this module than to use
    references

    String::Slice - Simple module that can make zero-copy substrings

    File::Map - Interface to "mmap()" that lets you "read in" a whole file
    into a string suitable for performing zero-copy substring operations

    LMDB_File - In-process database that supports zero-copy reads

AUTHOR
    Doug Hoyte, "<doug@hcsw.org>"

COPYRIGHT & LICENSE
    Copyright 2014 Doug Hoyte.

    This module is licensed under the same terms as perl itself.