~sircmpwn/aerc

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH] widgets/terminal: Only call vterm.ScreenCell.Attrs once in styleFromCell

Details
Message ID
<20210412232435.650971-1-clayton@craftyguy.net>
DKIM signature
pass
Download raw message
Patch: +6 -5
This fixes a substantial performance issue when scrolling emails with
long/complicated contents, where scrolling down a single line can take
something like hundreds of ms before the screen is updated to reflect
the scroll. It's really bad if the email has lots of columns, e.g. like
if it's an html email that was passed through a filter (w3m, etc) to
render it.

Using pprof, I found that the multiple calls to vterm.ScreenCell.Attrs()
in styleFromCell were really really expensive. This patch replaces them
with a single call.

Here's a before and after with a simple, but very manual test of opening
a large email with contents that went through a w3m filter and
continuously scrolling up and down over and over for ~30 seconds:

*** Before:

----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                            28.25s   100% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.PartSwitcher.Draw
         0     0% 99.94%     28.25s 82.31%                | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.PartViewer.Draw
                                            28.25s   100% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.Terminal.Draw
----------------------------------------------------------+-------------
                                            28.25s   100% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.PartViewer.Draw
         0     0% 99.94%     28.25s 82.31%                | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.Terminal.Draw
                                            19.23s 68.07% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.Terminal.styleFromCell
                                             6.04s 21.38% | github.x2ecom..z2fddevault..z2fgo..z2dlibvterm.Screen.GetCellAt
                                             1.38s  4.88% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2flib..z2fui.Context.Printf
                                             0.62s  2.19% | runtime.mapassign
                                             0.43s  1.52% | runtime.mapaccess2
                                             0.20s  0.71% | runtime.newobject
                                             0.19s  0.67% | runtime.callers (inline)
                                             0.07s  0.25% | runtime.makeslice
                                             0.07s  0.25% | runtime.mallocgc
----------------------------------------------------------+-------------
                                            19.23s   100% | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.Terminal.Draw
         0     0% 99.94%     19.23s 56.03%                | git.x2esr.x2eht..z2f..z7esircmpwn..z2faerc..z2fwidgets.Terminal.styleFromCell
                                            19.21s 99.90% | github.x2ecom..z2fddevault..z2fgo..z2dlibvterm.ScreenCell.Attrs

*** After:

----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                             0.31s   100% | git.x2esr.x2eht/~sircmpwn/aerc/widgets.Terminal.Draw
         0     0% 99.87%      0.31s  1.33%                | github.x2ecom/ddevault/go-libvterm.NewPos
                                             0.25s 80.65% | runtime.callers (inline)
                                             0.04s 12.90% | runtime.gomcache (inline)
----------------------------------------------------------+-------------
                                             8.40s   100% | github.x2ecom/ddevault/go-libvterm.Screen.GetCellAt
         0     0% 99.87%      8.40s 36.11%                | github.x2ecom/ddevault/go-libvterm.Screen.GetCell
                                             7.14s 85.00% | github.x2ecom/ddevault/go-libvterm._cgoCheckPointer
                                             0.54s  6.43% | runtime.callers (inline)
                                             0.35s  4.17% | runtime.exitsyscall
                                             0.11s  1.31% | runtime.deferprocStack
                                             0.07s  0.83% | doentersyscall
                                             0.07s  0.83% | runtime.getg
                                             0.05s   0.6% | runtime.casgstatus
                                             0.03s  0.36% |   _init
                                             0.03s  0.36% | runtime.gomcache (inline)
----------------------------------------------------------+-------------
                                             8.46s   100% | git.x2esr.x2eht/~sircmpwn/aerc/widgets.Terminal.Draw
         0     0% 99.87%      8.46s 36.37%                | github.x2ecom/ddevault/go-libvterm.Screen.GetCellAt
                                             8.40s 99.29% | github.x2ecom/ddevault/go-libvterm.Screen.GetCell
                                             0.06s  0.71% | runtime.callers (inline)
----------------------------------------------------------+-------------
                                             0.31s   100% | git.x2esr.x2eht/~sircmpwn/aerc/widgets.Terminal.styleFromCell
         0     0% 99.87%      0.31s  1.33%                | github.x2ecom/ddevault/go-libvterm.ScreenCell.Attrs
)
---
 widgets/terminal.go | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/widgets/terminal.go b/widgets/terminal.go
index f47f671..c9e7ce2 100644
--- a/widgets/terminal.go
+++ b/widgets/terminal.go
@@ -399,6 +399,7 @@ func (term *Terminal) styleFromCell(cell *vterm.ScreenCell) tcell.Style {

	background := cell.Bg()
	foreground := cell.Fg()
	attrs := cell.Attrs()

	var (
		bg tcell.Color
@@ -423,19 +424,19 @@ func (term *Terminal) styleFromCell(cell *vterm.ScreenCell) tcell.Style {

	style = style.Background(bg).Foreground(fg)

	if cell.Attrs().Bold != 0 {
	if attrs.Bold != 0 {
		style = style.Bold(true)
	}
	if cell.Attrs().Italic != 0 {
	if attrs.Italic != 0 {
		style = style.Italic(true)
	}
	if cell.Attrs().Underline != 0 {
	if attrs.Underline != 0 {
		style = style.Underline(true)
	}
	if cell.Attrs().Blink != 0 {
	if attrs.Blink != 0 {
		style = style.Blink(true)
	}
	if cell.Attrs().Reverse != 0 {
	if attrs.Reverse != 0 {
		style = style.Reverse(true)
	}
	return style
-- 
2.31.1
Details
Message ID
<20210417170029.45cnrag2inoir7am@feather.localdomain>
In-Reply-To
<20210412232435.650971-1-clayton@craftyguy.net> (view parent)
DKIM signature
pass
Download raw message
Hi there,

On Mon, Apr 12, 2021 at 04:24:35PM -0700, Clayton Craft wrote:
> This fixes a substantial performance issue when scrolling emails with
> long/complicated contents, where scrolling down a single line can take
> something like hundreds of ms before the screen is updated to reflect
> the scroll. It's really bad if the email has lots of columns, e.g. like
> if it's an html email that was passed through a filter (w3m, etc) to
> render it.

Merged, thank you :)
Reply to thread Export thread (mbox)