tumashu / posframe

Pop a posframe (just a child-frame) at point, posframe is a **GNU ELPA** package!
443 stars 57 forks source link

Improve posframe performance again. #101

Open seagle0128 opened 3 years ago

seagle0128 commented 3 years ago

https://github.com/tumashu/posframe/blob/739d8fd1081bdd0d20dee9e437d64df58747b871/posframe.el#L301-L307

请教下,我看到这里判断arg是否被修改,如果修改过就会删除并重新创建子窗口。很多场景下会造成一定程度的闪烁,打开时(比如 ivy-posframe)会有一点延迟。有没有可能直接用modify-frame-parameters 来复用child frame呢?这样是否能提高性能?

最近我在看mini-frame,发现在很多场景下性能会比posframe高些。mini-frame就是尽量复用已经创建的frame。不过,由于在Linux上表现不佳,我还是倾向于使用posframe,但是希望能改进性能。希望您能看看?很多细节我还不是很明白。谢谢!

(if (frame-live-p posframe--frame)
  ;; 复用现有frame
  (modify-frame-paremeters ...)
;;创建新frame
(make-frame ...))
seagle0128 commented 3 years ago

多次测试中发现,这个几个函数也可能很慢,但第二次运行又很快。

@zhenwenc 你有这个问题吗?

** Benchmark ‘posn-at-point’ 1000 times ...
Elapsed time: 16.952422s (0.156871s in 1 GCs)

** Benchmark ‘posn-x-y’ 1000 times ...
Elapsed time: 19.957894s

** Benchmark ‘posn-object-x-y’ 1000 times ...
Elapsed time: 20.668212s (0.182317s in 1 GCs)
zhenwenc commented 3 years ago

@seagle0128 多次测试会有差别,不过最高只到3秒左右。是不是跟窗口大小有关?

lynnux commented 1 year ago

我在windows头次使用会有2、3秒延迟应该是make-frame造成,可不可以在后台偷偷调用 make-frame呢,试了下mini-popup也是头次有延迟,但是我可以设置use-package的defer为0.5,然后在:config里添加上:

(setq mini-popup--frame (make-frame
                                 `((parent-frame . ,parent)
                                   (minibuffer . ,(minibuffer-window parent))
                                   ;; Set `internal-border-width' for Emacs 27
                                   (internal-border-width
                                    . ,(alist-get 'child-frame-border-width mini-popup--frame-parameters))
                                   ,@mini-popup--frame-parameters)))

也就做到了偷偷初始化,而我看posframe的make-frame的参数visibility也是nil,也就是初始化时实际都是不可见,但用的setq-local posframe--frame不知道是哪里的local,而上面mini-popup--frame是全局的比较好hack。当然我这里指单frame情况,多frame不考虑后台偷偷make-frame,因为我基本都是单frame。

tumashu commented 1 year ago

你可以试试用下面的代码偷偷初始化,不过我没有试过,window下从来我没感觉有2-3秒的延迟

(posframe-show "myposframe"
               :string ""
               :position '(0 . 0)
               :timeout 1)
lynnux commented 1 year ago

不好意思忘了说了,是想对vertico-posframe偷偷初始化。看了下posframe有参数变化的检测,从vertico-posframe拷贝过来的参数不可行。

(posframe-show " *Minibuf-1*"
               :string ""
               :font vertico-posframe-font
               :poshandler vertico-posframe-poshandler
               :background-color (face-attribute 'vertico-posframe :background nil t)
               :foreground-color (face-attribute 'vertico-posframe :foreground nil t)
               :border-width vertico-posframe-border-width
               :border-color (vertico-posframe--get-border-color)
               :override-parameters vertico-posframe-parameters
               :refposhandler vertico-posframe-refposhandler
               :hidehandler #'vertico-posframe-hidehandler
               :lines-truncate vertico-posframe-truncate-lines
               (funcall vertico-posframe-size-function)
               :position '(0 . 0)
               :timeout 1)
lynnux commented 1 year ago

OK,找到偷偷提前加载vertico-posframe的方法了,在启动一次vertico后,用下面代码找到保存的参数:

(dolist (frame (frame-list))
    (when (frame-parameter frame 'posframe-buffer)
      (message "%S" (frame-parameter frame 'last-args))))

*Messages*里找到打印的参数,如("args" "#c7c9cb" "#232530" nil nil 2 "#6a6a6a" nil nil nil nil nil nil nil nil) 然后设置vertico-posframe:

(use-package vertico-posframe
    :defer 0.5
    :config
    (vertico-posframe-mode)
    (set-frame-parameter (posframe--create-posframe " *Minibuf-1*" ) 'last-args '("args" "#c7c9cb" "#232530" nil nil 2 "#6a6a6a" nil nil nil nil nil nil nil nil))
    )