From 8e938064535a61f307740c10a10ddfb5196d6d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Tue, 23 Feb 2021 19:52:46 +0100 Subject: [PATCH] iconGrid: Cache visible children of pages We need to access the visible children of a page in inside vfunc_allocate(), and since getting those children is quite slow (it involves iterating over all the children of the actor) let's avoid that and cache the array instead. This reduces average time spent in vfunc_allocate() of the iconGrid from 1.6 ms down to 1.4 ms. Part-of: --- js/ui/iconGrid.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js index 12f1ac025..a06f92e57 100644 --- a/js/ui/iconGrid.js +++ b/js/ui/iconGrid.js @@ -437,8 +437,9 @@ var IconGridLayout = GObject.registerClass({ return this._childrenMaxSize; } - _getVisibleChildrenForPage(pageIndex) { - return this._pages[pageIndex].children.filter(actor => actor.visible); + _updateVisibleChildrenForPage(pageIndex) { + this._pages[pageIndex].visibleChildren = + this._pages[pageIndex].children.filter(actor => actor.visible); } _updatePages() { @@ -476,14 +477,14 @@ var IconGridLayout = GObject.registerClass({ if (pageIndex >= this._pages.length - 1) return; - const visiblePageItems = this._getVisibleChildrenForPage(pageIndex); + const visiblePageItems = this._pages[pageIndex].visibleChildren; const itemsPerPage = this.columnsPerPage * this.rowsPerPage; // No reduce needed if (visiblePageItems.length === itemsPerPage) return; - const visibleNextPageItems = this._getVisibleChildrenForPage(pageIndex + 1); + const visibleNextPageItems = this._pages[pageIndex + 1].visibleChildren; const nMissingItems = Math.min(itemsPerPage - visiblePageItems.length, visibleNextPageItems.length); // Append to the current page the first items of the next page @@ -505,8 +506,10 @@ var IconGridLayout = GObject.registerClass({ page.children.splice(itemIndex, 1); + this._updateVisibleChildrenForPage(pageIndex); + // Delete the page if this is the last icon in it - const visibleItems = this._getVisibleChildrenForPage(pageIndex); + const visibleItems = this._pages[pageIndex].visibleChildren; if (visibleItems.length === 0) this._removePage(pageIndex); @@ -515,7 +518,7 @@ var IconGridLayout = GObject.registerClass({ } _relocateSurplusItems(pageIndex) { - const visiblePageItems = this._getVisibleChildrenForPage(pageIndex); + const visiblePageItems = this._pages[pageIndex].visibleChildren; const itemsPerPage = this.columnsPerPage * this.rowsPerPage; // No overflow needed @@ -559,6 +562,8 @@ var IconGridLayout = GObject.registerClass({ visibleId: item.connect('notify::visible', () => { const itemData = this._items.get(item); + this._updateVisibleChildrenForPage(itemData.pageIndex); + if (item.visible) this._relocateSurplusItems(itemData.pageIndex); else if (!this.allowIncompletePages) @@ -572,6 +577,7 @@ var IconGridLayout = GObject.registerClass({ item.icon.setIconSize(this._iconSize); this._pages[pageIndex].children.splice(index, 0, item); + this._updateVisibleChildrenForPage(pageIndex); this._relocateSurplusItems(pageIndex); } @@ -779,21 +785,18 @@ var IconGridLayout = GObject.registerClass({ let nChangedIcons = 0; this._pages.forEach((page, pageIndex) => { - const visibleItems = - page.children.filter(actor => actor.visible); - if (isRtl && this._orientation === Clutter.Orientation.HORIZONTAL) pageIndex = swap(pageIndex, this._pages.length); - visibleItems.forEach((item, itemIndex) => { + page.visibleChildren.forEach((item, itemIndex) => { const row = Math.floor(itemIndex / this.columnsPerPage); let column = itemIndex % this.columnsPerPage; if (isRtl) column = swap(column, this.columnsPerPage); - const rowPadding = this._getRowPadding(visibleItems, itemIndex, - childSize, hSpacing); + const rowPadding = this._getRowPadding(page.visibleChildren, + itemIndex, childSize, hSpacing); // Icon position let x = leftEmptySpace + rowPadding + column * (childSize + hSpacing); @@ -929,7 +932,7 @@ var IconGridLayout = GObject.registerClass({ return [-1, -1]; const itemData = this._items.get(item); - const visibleItems = this._getVisibleChildrenForPage(itemData.pageIndex); + const visibleItems = this._pages[itemData.pageIndex].visibleChildren; return [itemData.pageIndex, visibleItems.indexOf(item)]; } @@ -947,7 +950,7 @@ var IconGridLayout = GObject.registerClass({ if (page < 0 || page >= this._pages.length) return null; - const visibleItems = this._getVisibleChildrenForPage(page); + const visibleItems = this._pages[page].visibleChildren; if (position < 0 || position >= visibleItems.length) return null; @@ -1056,7 +1059,7 @@ var IconGridLayout = GObject.registerClass({ const halfHSpacing = hSpacing / 2; const halfVSpacing = vSpacing / 2; - const visibleItems = this._getVisibleChildrenForPage(page); + const visibleItems = this._pages[page].visibleChildren; for (const item of visibleItems) { const childBox = item.allocation.copy();