测试结果在10楼 mimalloc结合emacs确实提升了windows上的使用体验(应该没啥用) - #10,来自 junmoxiao
之前看了猫哥发的gc分析,有提到频繁触发gc。如果使用mimalloc这种工具应该能提升性能把。还解决了内存碎片的问题。
特别是在win上用emacs,时不时卡顿。
linux上启用也很简单
LD_PRELOAD=/usr/lib/libmimalloc.so emacs
win上得处理下编译过程
2023-6-28 update
如果程序链接了ucrtbase.dll
,可以通过黑科技直接加载mimalloc 。
使用起来,感觉上速度确实得到了提升。 感兴趣的可以自己做下测试。
windows上的操作方法如下,
1 安装msys2的ucrt版emacs (也可以自己编译,但是得用ucrt的,ucrt的得patch下源码,可以参考msys2的构建脚本https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-emacs
)
pacman -S mingw-w64-ucrt-x86_64-emacs
2 下载mimalloc并用vs编译,会得到 mimalloc-override.dll
和 mimalloc-redirect.dll
,复制到/msys2/ucrt64/bin/
下,和emacs.exe
同级
ide/vs2019/mimalloc.sln
3 使用cff explorer给emacs添加导入表
下载地址 https://down.52pojie.cn/Tools/PEtools/CFF_Explorer.zip
先把 /ucrt/bin/emacs.exe 备份一下,然后用cff打开
import_adder - add - mimalloc-override.dll
选择DllMain - import by name - rebuild import table - 保存,覆盖原文件
然后打开runemacs.exe即可
4 验证是否加载成功,启动emacs之后,打开process explorer,查看emacs进程加载的dll,如下即成功
16 个赞
哪些方面有比较明显的提升呢?没有数据对比,感觉有时候不太可靠。
mimalloc就是加快底层内存释放分配,当频繁触发malloc free的时候就会更快。
还有些优化内存占用的效果。
典型的场景就是批量打开文件处理,然后关闭。
我不是很清楚emacs上怎么做测试,大佬可以写代码测一下?
个人感受的话,我在win11上用emacs,裸emacs find-file
有时候都会卡顿。用上mimalloc之后没感觉过卡顿。
Lee
4
我在 Linux 上试了一下,个人感觉没有提升。
(defun fibonacci(n)
(if (<= n 1)
n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(setq native-comp-speed 3)
(native-compile #'fibonacci)
(let ((time (current-time)))
(fibonacci 40)
(message "%.06f" (float-time (time-since time))))
在网上找的,不知道合不合适。
这种单纯计算的应该不受影响,得涉及频繁堆内存分配释放的。
eslip底层我不知道咋实现递归的,但是如果是c,递归只是移动栈指针也不受影响。
发现个特别明显的场景
用了mimalloc的只会卡emacs,不用的话整个电脑都卡得动不了
我也不知道这个为啥会突然耗这么多内存,不用mimalloc的时候,突然占用十几个g的内存,然后降一点
,我电脑有画面的时候显示8G
下图是用了mimalloc的,只是emacs卡得动不了
看上去挺有用的,等 emacs 29 出了我也折腾下
昨天写了个代码,频繁分配释放buffer,测出来并没有区别,今天看了下emacs的源码,貌似他并没有用malloc和free,而是直接调用的系统api
估计就只有上面那种特殊情况才会生效
macOS中使用动态加载mimalloc的方式,没有感觉到性能提升。MIMALLOC_SHOW_STATS=1
设置后,emacs在退出时没打印统计信息,可能和楼主说的一样,没有malloc函数吧。
人们常说的卡顿,一般是发生在 GC , 这个 GC 是 emacs 内部的垃圾回收,此时瓶颈不在调用系统的 malloc/free 上。。。
是的,只是gc底层也是得跟系统要内存,释放内存的,如果底层获取内存释放内存更快的话或许也有缓解
之前我看文档提到合并多少就会释放,结果他这个释放不是用free。
不过看源码里面也有关于内存分配器相关的设置,只是比较复杂,有空再研究了
这个错误已经被 Don't return long line to Emacs, Emacs will freeze when render very l… · manateelazycat/blink-search@01d0de7 · GitHub 修复了。
这个卡死的原因是, rg 没有卡死, blink-search 也没有卡死, 而是 blink-search 找到一个 50万字符的超长行, 当Emacs针对这个50万字符长度的单行进行关键字渲染的时候, Emacs就直接卡死了。
上面的补丁的作用是发现超过1000长度的单行的内容就直接不显示了。
1 个赞
consult-ripgrep也是这么处理的,但是他偶尔也会遇到卡死的情况
lsp-bridge和blink-search只要过滤这些条件后,可以保证永远不卡emacs,因为这些极端情况都被隔离在外部进程中。
而纯elisp只要遇到这种超长字符串,它只要处理就卡。
同时blink-search的虚拟列表技术,即使遇到全盘搜索也永远不会触发gc卡顿。
这就是为啥blink-search要比纯elisp搜索框架要快很多的原因,极限情况比ivy都要快很多。
2 个赞
blink-search是不是也像上面consutl-ripgrep这样显示好一点,显示在哪个文件忽略了一个长行,不然直接忽略这个搜索结果还以为真的不存在