Skip to content
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

take!(::IOBuffer) does make copies #27442

Merged
merged 1 commit into from
Apr 20, 2021
Merged

take!(::IOBuffer) does make copies #27442

merged 1 commit into from
Apr 20, 2021

Conversation

mbauman
Copy link
Sponsor Member

@mbauman mbauman commented Jun 5, 2018

Simple doc change to reflect the implementation.

@mbauman mbauman added the domain:docs This change adds or pertains to documentation label Jun 5, 2018
@stevengj
Copy link
Member

stevengj commented Jun 5, 2018

As far as I can tell, take! still does not make a copy on 0.7:

julia> buf = IOBuffer(); println(buf, "some stuff...")

julia> pointer(buf.data)
Ptr{UInt8} @0x0000000116f331c8

julia> b = take!(buf); pointer(b)
Ptr{UInt8} @0x0000000116f331c8

julia> pointer(buf.data)
Ptr{UInt8} @0x0000000116e52198

Notice that take! returns an array that points to the same memory location as the previous buf.data, after which buf.data is reset to a new (empty) array.

@mbauman
Copy link
Sponsor Member Author

mbauman commented Jun 5, 2018

Yes, that is true in the b.data isa Array{UInt8} && b.writeable && b.seekable case. In all other cases, a copy is made.

@stevengj
Copy link
Member

stevengj commented Jun 5, 2018

The writeable case is the most common case in which you would use take!...

@mbauman
Copy link
Sponsor Member Author

mbauman commented Jun 5, 2018

Ok, so would you like this docstring to remain as it is? Or what's your alternative?

If b.data isn't a Vector{UInt8} we make a copy. Arguably this falls "outside" the documentation since this is documenting the IOBuffer method (and not the GenericIOBuffer method). It's also fairly obvious that we cannot return a Vector{UInt8} from a different kind of abstract array without making a copy.

If !b.seekable, we make a copy.

If !b.writable, we make a copy. This is another fairly common case:

julia> b = IOBuffer("asdf")
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=4, maxsize=Inf, ptr=1, mark=-1)

julia> pointer(b.data)
Ptr{UInt8} @0x00007f5dcab57b38

julia> pointer(take!(b))
Ptr{UInt8} @0x00007f5dcace2990

julia> pointer(b.data)
Ptr{UInt8} @0x00007f5dcab57b38

In my opinion we shouldn't make promises about not copying in the docstring.

@stevengj
Copy link
Member

stevengj commented Jun 6, 2018

Maybe: "In the common case where an IOBuffer is created for writing (and is seekable), take! returns the underlying buffer without making a copy."

@ViralBShah
Copy link
Member

@mbauman Would it be possible to update this one and get it in?

@mbauman
Copy link
Sponsor Member Author

mbauman commented May 8, 2020

I wish I could remember how I got bit by this, but I had been trusting the docstring not to make copies and got surprised when it did. I don't really like documenting all the fiddly conditions in which this happens to not take a copy; it's quite fiddly (b.data isa Array{UInt8} && b.writeable && b.seekable).

Seems simpler just not to promise it.

@ViralBShah
Copy link
Member

Yes, it does seem simpler not to promise it. Can you rebase this one?

Simple doc change to reflect the implementation.
@vtjnash vtjnash merged commit 002fc5f into master Apr 20, 2021
@vtjnash vtjnash deleted the mb/doctake! branch April 20, 2021 13:41
ElOceanografo pushed a commit to ElOceanografo/julia that referenced this pull request May 4, 2021
Simple doc change to reflect the implementation.
antoine-levitt pushed a commit to antoine-levitt/julia that referenced this pull request May 9, 2021
Simple doc change to reflect the implementation.
johanmon pushed a commit to johanmon/julia that referenced this pull request Jul 5, 2021
Simple doc change to reflect the implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:docs This change adds or pertains to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants