Another approach would be to just pre-allocate a byte array and wrap it in
a string last:

function bytes2hex(bytes::Vector{Uint8})
    buf = Array(Uint8, 2*length(bytes))
    for i = 1:length(bytes)
        b = bytes[i]
        buf[2i-1] = Base.Printf.hex_symbols[1 + (b >> 4)]
        buf[2i]   = Base.Printf.hex_symbols[1 + (b & 15)]
    end
    return ASCIIString(buf)
end


Getting the compiler to be smart enough to avoid allocating lots of strings
for this kind of thing is pretty tricky – consider that Java doesn't do
this despite the large amount of work that's gone into that system. The new
design we're working on for strings would help by making each of these
short strings an immediate 16-byte object.

On Mon, Dec 1, 2014 at 12:46 AM, John Myles White <[email protected]>
wrote:

> This should help a bit, although there's probably some room for
> improvement by replacing the hex(byte, 2) calls with something that doesn't
> allocate an intermediate string object:
>
> function bytes2hex(bytes::Vector{Uint8})
>         io = IOBuffer()
>         for byte in bytes
>                 write(io, hex(byte, 2))
>         end
>         return takebuf_string(io)
> end
>
> bytes2hex([0x01, 0x23, 0xab, 0xff]) # => "0123abff"
>
>  -- John
>
> On Nov 30, 2014, at 9:39 PM, Ronald L. Rivest <[email protected]>
> wrote:
>
> > Suppose you have a length-n array x of Uint8's = [1,5,32,7,...] , and
> you want to convert this
> > to a long string of hex digits (two per x[i]).  The code
> >       y = reduce(string, [hex(xi,2) for xi in x])
> >       ==> "01052007..."
> > will do the trick.  (Or, you could use map_reduce or one of the fold
> operations.)
> >
> > But I would like this operation to run in linear time.
> >
> > Would any of the reduce, map_reduce, or fold operations run in linear
> time?
> > With a strict abstract implementation, each intermediate result string
> would need to
> > be created, and each such intermediate result string is immutable, so
> the running
> > time would be Theta(n^2).
> >
> > Or is the compiler smart about this case?  (A small experiment suggests
> not.)
> >
> > Perhaps the right approach is:
> >        x2 = [ hex(xi,2) for xi in x]
> >        y = string(x2)
> > ??
> >
> > Cheers,
> > Ron
>
>

Reply via email to