这样还不如用pdumper的序列和反序列化函数呢, 应该比read性能好吧?
go routine 用的 green thread 和 system thread 什么区別你先了解一下。green thread 实际上根本没有跨线程。
总感觉你和我不在一个频道上,另外你真的了解你说出来的那些术语吗?
这个序列化是浏览器实现的, worker可以不管, worker里面就是传js对象. 同一种对象, 内部序列化反序列化, 就类似c++的拷贝构造, 性能很高, 跟json, 以及lisp的read不是一个级别.
golang里面也是可以传对象指针的, 这个指针完全没有拷贝, 就是直接传.
你可以具体一点.
具体一点就是Elisp的thread就类似你称赞的Golang的green thread。此外JS worker里是不能做很多带全局副作用的代码的,同样在Lisp thread里面这样搞就会卡
切题一下,不局限Lisp code的话,Rust module里开N个系统线程跑Rust code是没问题的。
你也可以详细一点嘛,你说“异步”结果大家发现你想要的是并行,现在Web Worker讲半天,terminology都对不上,要交流还是很困难的。
记得golang用的实际上是mn thread,多个system thread和多个“green thread”。
用户态线程对吧? 这个好像是golang内部自动管理的.
如果一个routine里面运行 while(1), 另外一个routine还能正常运行, 这不就是我要的效果吗? 这样底层怎么处理就没关系了吧?
刚做了一个测试, 创建两个routine, 各自运行如下循环:
while true {
i++
}
cpu占用200%.
这不就是并发吗? 我要的就是这个效果啊.
对. 他认为golang的routine不是真并发, 这个应该是不对的.
你只要 routine 数上百个就能看到区別了。
golang的routine不是全用户态线程, 底层自动给它分配内核线程, M对N的关系. 这个基础我们先统一一下.
我认为js的worker跟go routine类似, 至少从上层开发者角度看是类似的, 就是真并发. golang里多个routine可以自由传递对象指针, 而且没什么成本. web worker可能有更严格的限制, 但是传递数据性能不会很差, 类似protobuffer, 甚至可以优化成对象拷贝. 这个就取决于底层实现了.
我的意思: "异步"一个词表示简单的并行, "真异步"表示真正的100%异步(即不需要切换, 可多核并行运行), 即真并发. 我表达能力有点欠缺.
我记得golang默认内核线程数量是等于cpu核心数. 数百个routine, 依然是这些内核线程. 对我来说没问题. 可以把所有cpu核心占满就ok了. 我们还需要关心更多吗?
routine 足够多的时候无法保证每个都能运行,只能靠自行协调,这就是问題。
然而重點不在昰不是异步,重点在只要有 reference 就得靠 serialize 传数据。go 没有 reference ,但显然 JS 和 Emacs Lisp 都有 reference
关于序列化, 找到了更详细一点的信息, 结构化拷贝, 性能应该比较高. 跟我的猜测差不多.
worker中数据的接收与发送:详细介绍
在主页面与 worker 之间传递的数据是通过 拷贝 ,而不是共享来完成的。传递给
worker
的对象需要经过序列化,接下来在另一端还需要反序列化。页面与worker
不会共享同一个实例, 最终的结果就是在每次通信结束时生成了数据的 一个副本。 大部分浏览器使用结构化拷贝来实现该特性。
routine 足够多的时候无法保证每个都能运行,只能靠自行协调,这就是问題。
这个问题不大, 记得golang之前的routine调度好像是出现在函数调用返回的地方. 就是说只要你的routine里调用了函数, 该函数返回的时候, 会进入golang的调度代码. 它能帮你公平调度, 不会让你不停运行不给其他routine机会, 很少有不调用函数的代码块.
它不全是通过IO阻塞点来调度的, 所以基本没有什么局限性.
新版本的调度好像更高级了.
然而重點不在昰不是异步,重点在只要有 reference 就得靠 serialize 传数据。go 没有 reference ,但显然 JS 和 Emacs Lisp 都有 reference
这个是有点局限性, 看来go这方面确实先进一步.
切题一下,不局限Lisp code的话,Rust module里开N个系统线程跑Rust code是没问题的。
是没什么问题, 跟子进程比没啥优势, 传输数据量大的时候, 性能是个问题, 会成瓶颈.
我们希望的可能是用lisp来写这些线程, 而且真并发, 且对象可直接传递, 或者拷贝传递.
如果不考虑数据传输性能的话, 其实可以做一个emacs模块, 在里面创建一个或多个guile环境, 然后在guile里开发, 依然是lisp, 而且兼容elisp.
是没什么问题, 跟子进程比没啥优势, 传输数据量大的时候, 性能是个问题, 会成瓶颈.
对于rust native的对象,Rust module里可以直接对Lisp VM嵌入user-ptr,没有你说的解码编码的问题。
然后在guile里开发, 依然是lisp, 而且兼容elisp.
除了Guile Emacs(勉强支持到24)有可行的用Guile跑Elisp的应用吗(笑)
而且并没有所谓“轻量” Elisp VM,要起一个Elisp VM就只能像emacs -Q
那样起一个重量的,毕竟诸如buffer,marker这些和Elisp VM是紧密结合的。
Rust module里可以直接对Lisp VM嵌入user-ptr,没有你说的解码编码的问题。
这个user-ptr怎么给emacs里的lisp使用? 是一个lisp对象吗? 比如list或者hash表?
比如lsp的补全列表数据.
除了Guile Emacs(勉强支持到24)有可行的用Guile跑Elisp的应用吗(笑)
只是想象一下. 如果好用, 流行起来肯定没问题. 实际上由于数据传输性能, 可能并不好用.
另外, 之前看了guile的一些文档, 没有找到网络相关的函数, 不知道是不是不支持, 这样的话, 功能是太简陋了.
这个user-ptr怎么给emacs里的lisp使用? 是一个lisp对象吗? 比如list或者hash表?
通过module function使用,我觉得我这文章应该有提到过
学习一门语言,最好的方式就是在实践中学习使用。自接触Rust语言一来,我一直在寻找使用这门语言的机会。 前几个月,我接触到了 ubolonto 的 GitHub - ubolonton/emacs-module-rs: Rust binding and tools for Emacs's dynamic modules ,这个crate让用Rust开发Emacs dynamic module成为可能。 于是在与Emacs联手大战Rust编译器后,我整理出了这篇文章,希望可以破除一部分Emacs hacker对dynamic module “望而生畏” 的心态,同时对不了解Rust和emacs-module-rs的Hacker一份中文的简易教程。 TOC(被discourse裁剪,请点击大图查看完整列表): [image] 文章地址:用Rust扩展Emacs功能 | NIL 写这样的一篇文章需要耗费很多时间和精力来踩坑以及和想玩游戏的欲望斗智斗勇,如果你们觉得这篇文章对你有帮助,欢迎移步 我 | NIL 进行捐赠。 注意:虽然我是管理员,但是捐赠的金额为本人所有,与论坛…
比如lsp的补全列表数据.
恕我不参加关于LSP性能的讨论,因为我用LSP(除了rls自己的问题)没有感受到卡顿