作者不读 Rust,就让智能体改写
Piotr Sarnacki 在 10 月 11 日写道,Ruby on Rails 的作者 DHH 要把 Campfire Once 从 Rails 改写成 Rust。更准确地说,是让智能体去写,因为 DHH 受不了自己读或写 Rust。之后他又加了 Elixir 和 Go 的重写。
Sarnacki 把这看成一个样本:编程经验很多的人,用智能体改代码,自己不读结果。他的判断是,如果指望很快就能不读代码、也不再自己想,这些重写并不让人放心。
[1]
提示没写清的地方,兼容性被改掉了
他先看功能以外的差异。要不要保持向后兼容、更在意延迟还是吞吐、负载下能用多少内存、崩溃以后丢掉新内容通知能不能接受,这些问题往往没有唯一正确答案。提示里没写明,模型在实现时就会自己作答。
Rust 这一版没有保持百分之百的向后兼容。文中的例子是,它去掉 CSRF token,以便缓存更容易做;它还丢掉 Redis,改用进程内队列,例如用来发送通知。Elixir 的重写更接近原来的 Rails。Sarnacki 认为,这些差别跟用哪门语言无关。不是因为提示写成用 Elixir 重写,模型就由于这门语言而决定守住兼容。
CSRF token 在这里只是被拿掉的一项控制,用来说明原有行为没守住。
[1]百分之一的送达率,两边数的不是同一批事件
Zach Daniels 在高负载下量过新帖通知的送达。Rust 版在大约 6 千到 7 千条通知里大约送达 1%。Elixir 版在大约 1.7 千条里送达了 100%。Sarnacki 说,这表示 Elixir 更能处理回压,而且只在请求量还没有把系统压垮时成立。
两边都是闭环测试:若干客户端,每收到上一条的响应就立刻发下一条,问的是一段固定时间里能处理多少请求。Rust 处理的请求大约是 Elixir 的 4 倍,于是要通过 WebSocket 发给客户端的事件也更多。只拿送达百分比说哪门语言更强,口径并不对齐。
[1]换成固定速率,另一边开始超时
Sarnacki 用固定到达速率重跑了 DHH 的 Rust 版和 Zach 改过的 Elixir 版。每秒 100 次 POST 时,Rust 的客户端大约收到 14% 的事件,HTTP 没有报错。Elixir 大约收到 60% 的事件,但大约 23% 的 POST 超时。Elixir 最差的事件送达延迟接近 180 秒。Rust 在送达落后时会把客户端断开。浏览器重连以后会去取最新消息,没送到的事件就没那么必要。
他比较的是两种体验:客户端在后台重连并拉取新内容,或者为一则新消息等上三分钟。一个数字说不完。
Rust 版用有容量上限的广播通道,把新消息事件发给已连接的客户端。容量设成 256。接收端来不及处理,就会落后并报错。Elixir 里负责送达的进程,默认邮箱没有上限。
Sarnacki 把 Rust 的这条容量从 256 改成 16384。每秒 100 次请求时,送达率从大约 14% 升到大约 90%。他认为这一版其实更差:与其极慢地处理,不如尽快失败,让客户端重连。事件送达延迟的 pMAX 从 11 秒升到超过 130 秒,和 Elixir 那一类表现相近。他认为这比断开落后的客户端更糟。按他的看法,连 11 秒也太长,接收端传不了这么快,就应该丢掉这条事件。
同一场每秒 100 次请求的压测里,Elixir 版内存用到 1.8GB。他留下的问题是:丢掉一些消息,还是被内存打满之后杀掉,哪一种更好。Elixir 不会自动修掉所有并发问题。无论用哪门语言,失败时怎么处理都要自己定。Go 的重写没有对等的数字,这里不补。
[1]