fatteneder / MakieSlides.jl

MIT License
17 stars 2 forks source link

Using MakieLayout for rendering Markdown tables #3

Open fatteneder opened 2 years ago

fatteneder commented 2 years ago

In #1 concerns were raised regarding potential performance issues if we rely too much on MakieLayout to implement rendering of Markdown.Tables.

Here is a brief screencast of an implementation that renders each cell with a FormattedLabel and puts it into a GridLayout: formattedtable-gridlayout

There are 33 rows x 6 columns = 198 cells rendered and I am resizing the window in a way I would not recommend doing in a presentation :laughing:. To me this looks ok for a table that would rather belong into a spreadsheet than into a presentation.

In this example there is no line wrapping going on, but I noticed that the program pauses for a little (~2 secs) when it has to recompute line breaks, which happens when you make the window unreasonably narrow.

Regarding the caching idea: I think the expensive part here is not the actual GridLayout creation (which only happens once), but rather the recomputation of all the box layouts, because the former cannot be altered by window resizing. Of course, rendering to images and displaying those would make all these concerns obsolete.

EDIT: Embed gif here.

ffreyer commented 2 years ago

There's another issue I stumbled over while working on Presentations: The number of scenes in GLMakie is limited to 255 (UInt8). And since the changes from Layoutable -> Block every layout element has its own Scene. If you do a 31x8 table you'll get an InexactError because of this.

asinghvi17 commented 2 years ago

You could, theoretically, roll your own initialize_block! method as in

https://github.com/JuliaPlots/Makie.jl/blob/89da9ccc79b8422504f654d85019905a190b54c4/src/makielayout/blocks.jl#L288

and change it to not create a new blockscene. This might be a bit fragile depending on upstream changes, though...

fatteneder commented 2 years ago

You could, theoretically, roll your own initialize_block! method as in ...

I am curious about whether changing UInt8 to UInt16 in GLMakie.jl would alter the performance/optimization drastically? Or what is the reason for using UInt8 here?

Do I understand correctly that the limit only applies to one figure? E.g. we could have multiple slides with tables up to 255 cells each?

ffreyer commented 2 years ago

I am curious about whether changing UInt8 to UInt16 in GLMakie.jl would alter the performance/optimization drastically? Or what is the reason for using UInt8 here?

It's used to associate pixels with different scenes through a stencil buffer for scene.clear. The stencil buffer is combined with the depth buffer, so increasing the stencil buffer to UInt16 would also require separating the depth buffer and resizing to 16 or 32 Bit from 24. So not the easiest thing to do. There are also some performance concern with increasing buffer sizes, though on this level it's probably fine. (After I added SSAO some people had issues, but that added 100-200Bit per pixel. Not sure about the exact numbers anymore)

Do I understand correctly that the limit only applies to one figure? E.g. we could have multiple slides with tables up to 255 cells each?

Yup. It's per window and at a given time.

I also noticed in the mwe that the list (and similarly a large table) is what takes a noticable amount of time to generate. The list takes a bit more than a second for me, with about half that time spend on creating each FormattedLabel.

fatteneder commented 2 years ago

Regarding the 255 cells limit: I am almost tempted to say that this not a limit we should be concerned with, at least for tables and lists. Or when was the last time you saw a slide with such a huge table or list? Not even talking about whether it was readable on a beamer or even informative.

I for myself tend to keep slides simple and try to only discuss one issue at a slide, e.g. prefer pictures and plots over text, formulae, tables and lists. Not saying we shouldn't use those tools, but rather that we should use them sparingly. Of course, your millage way very ...

If one really needs to present such a table (again, it might not even be readable from the audience), one could use alternative approaches:

  1. try to plot the data and show the plot (if possible),
  2. split it across multiple slides (if possible),
  3. switch screens to an actual spreadsheet (I can image that such data already comes from a spreadsheet; parsing the data into a Markdown table format also seems unnecessary),
  4. include a picture/screenshot from the spreadsheet.

That is obviously a biased view on presentation philosophy. From a programming POV it certainly bugs me :sweat_smile:

What do you say?

fatteneder commented 2 years ago

I also noticed in the mwe that the list (and similarly a large table) is what takes a noticable amount of time to generate. The list takes a bit more than a second for me, with about half that time spend on creating each FormattedLabel.

Can confirm the lag, though it is a little less than a second for me.

Timing the table in test/formattedtable.jl gives the results:

julia> include("test/formattedtable.jl")
  7.420614 seconds (33.57 M allocations: 1.848 GiB, 8.03% gc time)

julia> include("test/formattedtable.jl")
  7.409750 seconds (33.57 M allocations: 1.848 GiB, 9.39% gc time)

julia> include("test/formattedtable.jl")
  7.328339 seconds (33.57 M allocations: 1.848 GiB, 9.51% gc time)

Temporarily disabling the FormattedLabel's background box (the poly! call) improves things, but there are still more than 1G allocations:

julia> include("test/formattedtable.jl")
  4.960201 seconds (27.35 M allocations: 1.546 GiB, 10.31% gc time, 10.22% compilation time)

julia> include("test/formattedtable.jl")
  4.572011 seconds (26.55 M allocations: 1.502 GiB, 17.01% gc time)

julia> include("test/formattedtable.jl")
  4.055608 seconds (26.53 M allocations: 1.502 GiB, 8.06% gc time)
fatteneder commented 2 years ago

For tables it seems like inserting a FormattedLabel into l.layout causes more allocations than the creation of the label itself.

fatteneder commented 2 years ago

https://github.com/JuliaPlots/Makie.jl/issues/1881 might be related.

fatteneder commented 2 years ago

After merging #10 I noted that the performance of FormattedTable degraded drastically, e.g. dynamic resizing as shown above does not work anymore and I have to wait for 2-3 secs for Makie to catch up with layouting whenever I resize the window.

fatteneder commented 2 years ago

20 should restore the behavior as it was at the start of this thread.

fatteneder commented 1 year ago

I think https://github.com/MakieOrg/Makie.jl/pull/2389 fixed the 255 cells limit. Need to upgrade Makie to v0.18.2 to test this.