Skip to content

Commit

Permalink
Use tobytes in hex to make data C contiguous
Browse files Browse the repository at this point in the history
Only copy the data in `hex` using `tobytes` if it is not C contiguous.
That way if the data is already C contiguous, a view onto the original
data can be used instead saving time and memory. The copy is needed for
non-C contiguous data to get a consistent representation in hex as
`memoryview` and other objects do. As Python 2's `binascii.hexlify`
supports the (new) buffer protocol, it won't introduce any additional
copies as long as something implementing the (new) buffer protocol is
provided. On Python 3, we leverage `memoryview`'s `hex` method, which
also avoids copying if the data is C contiguous. It provides a fast path
to `hex`, which is equivalent to the `bytes` method `hex`. Thus in both
cases, the hex conversion will avoid any additional copies of the data.
So this should in the best case avoid a copy when constructing the hex
result, but may still copy the data if it is not contiguous in the way
we expect, which is better than before.
  • Loading branch information
jakirkham committed Nov 24, 2018
1 parent af29c77 commit 38d2abd
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/cybuffer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ include "version.pxi"
cdef extern from "Python.h":
size_t Py_UNICODE_SIZE

object PyMemoryView_FromObject(object obj)


cdef extern from *:
"""
Expand Down Expand Up @@ -269,11 +271,18 @@ cdef class cybuffer(object):


cpdef str hex(self):
cdef object d
cdef str s

if self.c_contiguous:
d = self
else:
d = self.tobytes()

if PY2K:
s = hexlify(self.tobytes())
s = hexlify(d)
else:
s = self.tobytes().hex()
s = PyMemoryView_FromObject(d).hex()

return s

Expand Down

0 comments on commit 38d2abd

Please sign in to comment.