Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth + "Approximate the maximum width of this lazy list. Take all visible items as a sample. + + NOTE that we MUST compute the width for all items in view!! Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)." - "Approximate the maximum width of this lazy list. Take first n items as a sample."
+ | listSize visibleBounds topRow bottomRow | + maxWidth ifNotNil: [^maxWidth]. + - | threshold listSize | - maxWidth ifNotNil:[^maxWidth]. - - threshold := 30. listSize := self getListSize. + visibleBounds := self bounds: self owner bounds from: self owner. + topRow := self rowAtLocation: visibleBounds topLeft. + bottomRow := self rowAtLocation: visibleBounds bottomLeft. + maxWidth := 0. + topRow to: bottomRow do: [:index | - 1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self getListItem: index))]. + + ^ maxWidth! - - ^ maxWidth - !
On Sat, Jan 28, 2023 at 8:58 PM commits@source.squeak.org wrote:
Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
One of the best ways to test speed impact on huge lists is to explore bits in a Form. It takes a while to process a million elements :-D [bits explore]timeToRun 89621 Best, Karl
[image: image.png]
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth
"Approximate the maximum width of this lazy list. Take all visible
items as a sample.
NOTE that we MUST compute the width for all items in view!!
Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)."
"Approximate the maximum width of this lazy list. Take first n
items as a sample."
| listSize visibleBounds topRow bottomRow |
maxWidth ifNotNil: [^maxWidth].
| threshold listSize |
maxWidth ifNotNil:[^maxWidth].
threshold := 30. listSize := self getListSize.
visibleBounds := self bounds: self owner bounds from: self owner.
topRow := self rowAtLocation: visibleBounds topLeft.
bottomRow := self rowAtLocation: visibleBounds bottomLeft.
maxWidth := 0.
topRow to: bottomRow do: [:index |
1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self
getListItem: index))].
^ maxWidth!
^ maxWidth
- !
One of the best ways to test speed impact on huge lists is to explore bits in a Form.
It takes a while to process a million elements :-D [bits explore]timeToRun 89621
You're talking about trees, but this contributions was about lists. :-)
So far, we do not have managed to merge both into a unified framework ... Trees have true morphic nodes whereas lists optimize construction/memory, layouting, and rendering through a flat LazyListMorph. The advantage of the former are expressive, customizable object representations (e.g., for individual extents and formatting, submorphs, or interactive widgets to nodes) and support for exploration (scripting, halos) whereas the latter is significantly faster. I'm not sure which way we want to go in the long term. Can we make Morphic construction, layouting, and rendering lazy and fast enough to get rid of the LazyListMorph "hack" or do we have to build a LazyTreeMorph for fast huge trees (and add reification support/virtual halos for individual list/tree items (Marcel expressed this idea earlier))? It remains exciting ...
Best, Christoph
________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von karl ramberg karlramberg@gmail.com Gesendet: Sonntag, 29. Januar 2023 11:56 Uhr An: squeak-dev@lists.squeakfoundation.org Betreff: Re: [squeak-dev] The Inbox: Morphic-ct.2082.mcz
On Sat, Jan 28, 2023 at 8:58 PM <commits@source.squeak.orgmailto:commits@source.squeak.org> wrote: Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
One of the best ways to test speed impact on huge lists is to explore bits in a Form. It takes a while to process a million elements :-D [bits explore]timeToRun 89621 Best, Karl
[image.png]
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth + "Approximate the maximum width of this lazy list. Take all visible items as a sample. + + NOTE that we MUST compute the width for all items in view!! Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)." - "Approximate the maximum width of this lazy list. Take first n items as a sample."
+ | listSize visibleBounds topRow bottomRow | + maxWidth ifNotNil: [^maxWidth]. + - | threshold listSize | - maxWidth ifNotNil:[^maxWidth]. - - threshold := 30. listSize := self getListSize.
+ visibleBounds := self bounds: self owner bounds from: self owner. + topRow := self rowAtLocation: visibleBounds topLeft. + bottomRow := self rowAtLocation: visibleBounds bottomLeft. + maxWidth := 0. + topRow to: bottomRow do: [:index | - 1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self getListItem: index))]. + + ^ maxWidth! - - ^ maxWidth - !
Hi Christoph, hi all --
Hmm... I would rather not sacrifice performance for a little bit less flickering. I would not want to have sluggish systems that appear calm but actually slow you down.
I think that it is not expedient to modify (and break) snappy things like LazyListMorph but rather write a new list widget that might replace the current one. Then, we can avoid having an intermediate state without a way to go back or forth, depending on the situation.
Best, Marcel
Am 28.01.2023 20:58:16 schrieb commits@source.squeak.org commits@source.squeak.org:
Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth + "Approximate the maximum width of this lazy list. Take all visible items as a sample. + + NOTE that we MUST compute the width for all items in view!! Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)." - "Approximate the maximum width of this lazy list. Take first n items as a sample."
+ | listSize visibleBounds topRow bottomRow | + maxWidth ifNotNil: [^maxWidth]. + - | threshold listSize | - maxWidth ifNotNil:[^maxWidth]. - - threshold := 30. listSize := self getListSize.
+ visibleBounds := self bounds: self owner bounds from: self owner. + topRow := self rowAtLocation: visibleBounds topLeft. + bottomRow := self rowAtLocation: visibleBounds bottomLeft. + maxWidth := 0. + topRow to: bottomRow do: [:index | - 1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self getListItem: index))]. + + ^ maxWidth! - - ^ maxWidth - !
Hi Marcel,
thank you for the feedback! Just to make sure we are talking about the same "little flickering", I'm attaching an example from the Protocol Explorer.
I did not run any benchmarks but just speculated about the performance impact. Do we have any ready-to-use benchmarks for that? The current logic is very imprecise anyway, as you can also see when you scroll through a list and suddenly a column is growing. Thus, how would you think about modifying this patch with ...
topRow to: (bottomRow clampHigh: topRow + threshold)
... so we could at least fix this issue for any lists that show not more than 30 items in the viewport, which should apply to a remarkable portion of all lists in a typical Squeak Trunk image. Then it should not worsen performance unless you are concerned about the constant geometry/getListSize costs added by the patch.
Best,
Christoph
________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Taeumel, Marcel via Squeak-dev squeak-dev@lists.squeakfoundation.org Gesendet: Montag, 30. Januar 2023 11:06:24 An: gettimothy via Squeak-dev Betreff: Re: [squeak-dev] The Inbox: Morphic-ct.2082.mcz
Hi Christoph, hi all --
Hmm... I would rather not sacrifice performance for a little bit less flickering. I would not want to have sluggish systems that appear calm but actually slow you down.
I think that it is not expedient to modify (and break) snappy things like LazyListMorph but rather write a new list widget that might replace the current one. Then, we can avoid having an intermediate state without a way to go back or forth, depending on the situation.
Best, Marcel
Am 28.01.2023 20:58:16 schrieb commits@source.squeak.org commits@source.squeak.org:
Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth + "Approximate the maximum width of this lazy list. Take all visible items as a sample. + + NOTE that we MUST compute the width for all items in view!! Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)." - "Approximate the maximum width of this lazy list. Take first n items as a sample."
+ | listSize visibleBounds topRow bottomRow | + maxWidth ifNotNil: [^maxWidth]. + - | threshold listSize | - maxWidth ifNotNil:[^maxWidth]. - - threshold := 30. listSize := self getListSize.
+ visibleBounds := self bounds: self owner bounds from: self owner. + topRow := self rowAtLocation: visibleBounds topLeft. + bottomRow := self rowAtLocation: visibleBounds bottomLeft. + maxWidth := 0. + topRow to: bottomRow do: [:index | - 1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self getListItem: index))]. + + ^ maxWidth! - - ^ maxWidth - !
Hmm... looks like a fundamental issue. There should be no updates when the user is not interacting with the list.
We have a column-width cache in tree widgets. We could do that for multi-column-lists as well. I would not do that for all LazyListMorphs, however. Just from the outside via PluggableMultiColumnListMorph.
Let's not slow down single-column lists.
Best, Marcel
Am 30.01.2023 20:39:41 schrieb Thiede, Christoph christoph.thiede@student.hpi.uni-potsdam.de:
Hi Marcel,
thank you for the feedback! Just to make sure we are talking about the same "little flickering", I'm attaching an example from the Protocol Explorer.
I did not run any benchmarks but just speculated about the performance impact. Do we have any ready-to-use benchmarks for that? The current logic is very imprecise anyway, as you can also see when you scroll through a list and suddenly a column is growing. Thus, how would you think about modifying this patch with ...
topRow to: (bottomRow clampHigh: topRow + threshold)
... so we could at least fix this issue for any lists that show not more than 30 items in the viewport, which should apply to a remarkable portion of all lists in a typical Squeak Trunk image. Then it should not worsen performance unless you are concerned about the constant geometry/getListSize costs added by the patch.
Best,
Christoph
________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Taeumel, Marcel via Squeak-dev squeak-dev@lists.squeakfoundation.org Gesendet: Montag, 30. Januar 2023 11:06:24 An: gettimothy via Squeak-dev Betreff: Re: [squeak-dev] The Inbox: Morphic-ct.2082.mcz
Hi Christoph, hi all --
Hmm... I would rather not sacrifice performance for a little bit less flickering. I would not want to have sluggish systems that appear calm but actually slow you down.
I think that it is not expedient to modify (and break) snappy things like LazyListMorph but rather write a new list widget that might replace the current one. Then, we can avoid having an intermediate state without a way to go back or forth, depending on the situation.
Best, Marcel
Am 28.01.2023 20:58:16 schrieb commits@source.squeak.org commits@source.squeak.org:
Christoph Thiede uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ct.2082.mcz
==================== Summary ====================
Name: Morphic-ct.2082 Author: ct Time: 28 January 2023, 8:57:55.639628 pm UUID: dfcaa928-8758-5a42-a55b-2d89712a2a86 Ancestors: Morphic-mt.2081
To review: Fixes flickering in multi-column lists by ensuring sufficiently stable computation in #maxWidth.
This is likely to have a small but noticable negative impact on the performance for large lists, but I think this is inevitable if we want to avoid flickering. Otherwise, we could only consider computing the layout completely lazily during drawing.
For instance, the original bug can be reproduced by loading the SimulationMethodFinder from SimulationStudio, doing Morph new exploreProtocol and scrolling down until methodCommentAsBalloonHelp comes into view.
=============== Diff against Morphic-mt.2081 ===============
Item was changed: ----- Method: LazyListMorph>>maxWidth (in category 'layout') ----- maxWidth + "Approximate the maximum width of this lazy list. Take all visible items as a sample. + + NOTE that we MUST compute the width for all items in view!! Otherwise, maxWidth might be instable and be increased again during drawing in #item:, causing the receiver to flicker after each #layoutChanged (e.g., from PluggableMultiColumnListMorph>>#updateColumns)." - "Approximate the maximum width of this lazy list. Take first n items as a sample."
+ | listSize visibleBounds topRow bottomRow | + maxWidth ifNotNil: [^maxWidth]. + - | threshold listSize | - maxWidth ifNotNil:[^maxWidth]. - - threshold := 30. listSize := self getListSize.
+ visibleBounds := self bounds: self owner bounds from: self owner. + topRow := self rowAtLocation: visibleBounds topLeft. + bottomRow := self rowAtLocation: visibleBounds bottomLeft. + maxWidth := 0. + topRow to: bottomRow do: [:index | - 1 to: (threshold min: listSize) do: [:index | maxWidth := maxWidth max: (self widthToDisplayItem: (self getListItem: index))]. + + ^ maxWidth! - - ^ maxWidth - !
squeak-dev@lists.squeakfoundation.org