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

Showing a dict can be slow #9481

Closed
ncnc opened this issue Dec 28, 2014 · 5 comments
Closed

Showing a dict can be slow #9481

ncnc opened this issue Dec 28, 2014 · 5 comments
Labels
performance Must go faster status:help wanted Indicates that a maintainer wants help on an issue or pull request

Comments

@ncnc
Copy link
Contributor

ncnc commented Dec 28, 2014

The showkv function in dict.jl (latest master) contains the following code:

    for (i, v) in enumerate(iter)
        print(io, "\n  ")
        limit && i >= rows && (print(io, "⋮"); break)

        str = sprint(show, v)
        limit && (str = _truncate_at_width_or_chars(str, cols, "\r\n"))
        print(io, str)
    end

If v is "large", the above can be arbitrarily slow due to the sprint(show, v) part.

Below an example showing the problem from the REPL:

N = 1000000
d = Dict{ASCIIString,Array{Float64}}()
for i = 1:50
    d["Label $(i)"] = rand(N,1)
end
d   # takes a while to print

Increase N as necessary.

@mbauman
Copy link
Sponsor Member

mbauman commented Dec 29, 2014

Yup. This was my doing... and was why I then opened issue #5709 to try to figure out a consistent API to ask for a limited sprint. I'd be open to something better here, but I certainly prefer this to printing the whole v string.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 29, 2014

we could create an IOBuffer with a max length, and then catch the write error if it happens. not sure if that is the best solution, however.

@ncnc
Copy link
Contributor Author

ncnc commented Dec 29, 2014

@mbauman I agree that #5709 should cover this once it gets done. We definitely don't want to print the whole thing.

@vtjnash Interesting approach, if this issue starts bugging me enough I might give it a shot at some stage.

@ihnorton ihnorton added the domain:io Involving the I/O subsystem: libuv, read, write, etc. label Dec 30, 2014
@ihnorton ihnorton added the status:help wanted Indicates that a maintainer wants help on an issue or pull request label Jan 9, 2015
@hayd
Copy link
Member

hayd commented Feb 20, 2015

@vtjnash except for the failing early there's already a maxsize for IOBuffer (at least I don't think this fails early?). In fact there's already a sprint with a size option, though it's unclear to me if the intention was for this to be a sizehint or a maxsize:

s = IOBuffer(Array(UInt8,size), true, true, size)  # would make it a maxsize

@JeffBezanson JeffBezanson added performance Must go faster and removed domain:io Involving the I/O subsystem: libuv, read, write, etc. labels Feb 23, 2015
@JeffBezanson
Copy link
Sponsor Member

This works pretty well as a stop-gap:

diff --git a/base/dict.jl b/base/dict.jl
index a496b5d..1fed3f5 100644
--- a/base/dict.jl
+++ b/base/dict.jl
@@ -97,9 +97,11 @@ function showdict{K,V}(io::IO, t::Associative{K,V}; limit::Bo
         print(io, key)
         print(io, " => ")

-        val = sprint(show, v)
         if limit
+            val = with_output_limit(()->sprint(show, v))
             val = _truncate_at_width_or_chars(val, cols - keylen, "\r\n")
+        else
+            val = sprint(show, v)
         end
         print(io, val)
     end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster status:help wanted Indicates that a maintainer wants help on an issue or pull request
Projects
None yet
Development

No branches or pull requests

6 participants