[Libguestfs] [PATCH nbdkit] python: Pass memoryview to pwrite()

Nir Soffer nsoffer at redhat.com
Sat Nov 23 23:01:12 UTC 2019


On Sat, Nov 23, 2019 at 5:49 PM Nir Soffer <nirsof at gmail.com> wrote:
>
> Passing a memoryview we avoid unneeded copy of the original buffer. On
> the python side memoryview object can be used for slicing, writing to
> file, or sending to socket.
>
> This may break plugins assuming that the they get a bytearray, but
> good python code should not care about the type of the buffer, only
> about the behaviour.
>
> Testing with a plugin writing to /dev/null shows 2.7x speedup. Real
> plugin will probably show much smaller improvement.

I tested this with v2v, importing fedora 30 vm from local file to
ovirt, and it gives
about a 10% improvement in transfer time.

> Without patch:
>
> $ time qemu-img convert -p -f raw -O raw -n /var/tmp/disk.img nbd://localhost/
>     (100.00/100%)
>
> real    0m1.284s
> user    0m0.091s
> sys     0m0.576s
>
> With patch:
>
> $ time qemu-img convert -p -f raw -O raw -n /var/tmp/disk.img nbd://localhost/
>     (100.00/100%)
>
> real    0m0.477s
> user    0m0.078s
> sys     0m0.653s
> ---
>
> More info on how I tested this:
>
> # Creating test image
> $ dd if=/dev/zero bs=1M count=1024 | tr "\0" "U" > /var/tmp/disk.img
>
> $ cat zero.py
> import builtins
>
> def open(readonly):
>     return builtins.open("/dev/zero", "r+b")
>
> def get_size(h):
>     return 1024**3
>
> def pwrite(h, buf, offset):
>     h.write(buf)
>
> def pread(h, count, offset):
>     raise NotImplementedError
>
> def close(h):
>     h.close()
>
> # Running nbdkit
> $ ./nbdkit -f -v python zero.py
>
>  plugins/python/python.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/plugins/python/python.c b/plugins/python/python.c
> index 214fffb..2b4361a 100644
> --- a/plugins/python/python.c
> +++ b/plugins/python/python.c
> @@ -496,8 +496,8 @@ py_pwrite (void *handle, const void *buf,
>      PyErr_Clear ();
>
>      r = PyObject_CallFunction (fn, "ONL", obj,
> -                               PyByteArray_FromStringAndSize (buf, count),
> -                               offset, NULL);
> +            PyMemoryView_FromMemory ((char *)buf, count, PyBUF_READ),
> +            offset, NULL);
>      Py_DECREF (fn);
>      if (check_python_failure ("pwrite") == -1)
>        return -1;
> --
> 2.21.0
>





More information about the Libguestfs mailing list