Skip to content

avoid a copy in readuntil #19946

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 21, 2017
Merged

Conversation

stevengj
Copy link
Member

@stevengj stevengj commented Jan 9, 2017

This avoids a copy of the string data in readuntil(s::IO, delim::Char) when delim is ASCII and s is a file.

@kshyatt kshyatt added the io Involving the I/O subsystem: libuv, read, write, etc. label Jan 9, 2017
a `Vector{UInt8}`.
"""
readuntil_string(s::IO, delim::UInt8) = String(readuntil(s, delim))
function readuntil_string(s::IOStream, delim::UInt8)
Copy link
Contributor

@mpastell mpastell Jan 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to make this readuntil(s::IOStream, delim::UInt8) instead of giving this a new name? Also other documented methods using readuntil return a string.

I would rather rename the old readuntil to readbytes_until or read_until since it's not part of documented API anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, let's not add _string functions to the API at a time when we're rather trying to clean it (cf. removal of takebuf_string).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but that would be a breaking change.

(Though right now I can only find one package using the UInt8 version of readuntil.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if readuntil(io, delim::UInt8) is changed to return a string, people could just use Vector{UInt8}(readuntil(io, delim)) to get a UInt8 array (and it will still work in Julia 0.5), so maybe we won't need to define a separate method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. And couldn't you just do io <: IOStream && ccall(:jl_readuntil, ... inside the existing readuntil?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nalimilan, sure, but the Julian way to do this is to write methods rather than explicit type checks. In this case, I wrote a non-exported method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, due to the detailed docstring I thought it was exported. If it's not then I guess any approach is OK.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also thought it was exported, better to leave it as it is than to make breaking change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated to make it clearer that this is not exported, replacing the docstring with a comment

@KristofferC
Copy link
Member

@nanosoldier runbenchmarks("string", vs = ":master")

"""
readuntil_string(s::IO, delim::UInt8) = String(readuntil(s, delim))
function readuntil_string(s::IOStream, delim::UInt8)
ccall(:jl_readuntil, Ref{String}, (Ptr{Void}, UInt8, UInt8), s.ios, delim, 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changed in #19944, the new version is

ccall(:jl_readuntil, Ref{String}, (Ptr{Void}, UInt8, UInt8, UInt8), s.ios, delim, 1, 0)

where the last 0 is for chomp=false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depends on which PR gets merged first 😉

Like `readuntil(s, delim)`, but returns a `String` rather than
a `Vector{UInt8}`.
"""
readuntil_string(s::IO, delim::UInt8) = String(readuntil(s, delim))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generic version can go in io.jl.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - no performance regressions were detected. A full report can be found here. cc @jrevels

@stevengj
Copy link
Member Author

Should be ready to merge?

@stevengj stevengj merged commit b07b6dd into JuliaLang:master Jan 21, 2017
@stevengj stevengj deleted the readuntil_string branch January 21, 2017 20:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
io Involving the I/O subsystem: libuv, read, write, etc.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants