通过持久性来最小化脚本启动时间的方法?

uxe*_*xer 6 performance time fastcgi startup raku

Raku众所周知,启动时间非常


在我的机器上(旧机器,但我拥有的最现代的机器):

time raku -e 'put "Hello, World!"'
495.67 - 567.02 毫秒
(第一次发射 1.53 秒)

time perl -E 'say "Hello, World!"'
13.63 - 19.51 毫秒

time sh -c 'echo "Hello, World!"'
4.31 - 6.88 毫秒

c

#include <stdio.h>

int main(void) {
    puts("Hello, World!");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

time ./hello
5.03 - 7.67 毫利斯
time clang hello.c -o hello(编译)
126.39 - 195.66 毫利斯


Raku确实拥有许多内置的小技巧,这使它变得很重。
然而,有时您需要一个相当简单的脚本,并且您更喜欢Raku它的优雅,但等待的启动时间会带来不满,并且您不会选择Raku下一个简单的脚本。

有什么办法可以帮助它吗?
就像启动Raku一次并保持运行,并使其处理所有Raku脚本,无论有没有模块,无论大小,等等raku -e ...
类似于FastCGI但对于本地 shell 吗?


即使永久牺牲大量内存对我来说也比浪费时间等待更好。
以千字节为单位,根据ps

                                      Virtual size  Resident set size

raku -e 'loop {sleep 1}'                    146704  107200

perl -e 'while (1) {sleep 1}'                 1252    4036

sh -c 'while true; do sleep 1; done'           892     900

#include <unistd.h>
void main(void) { for(;;) {sleep(1);} }        172     780
Run Code Online (Sandbox Code Playgroud)

更新:

详细阐述
raku -e 'while prompt "Enter filename: " -> $filename { EVALFILE $filename }'
来自/sf/answers/5171143001/

https://docs.raku.org/type/IO::Socket::INEThttps://www.tutorialspoint.com/perl/perl_socket_programming.htm编写

raku-persistent,重型服务器:

#! /usr/bin/env raku

use MONKEY-SEE-NO-EVAL;

my $listen = IO::Socket::INET.new( :listen,
                                   :localhost<localhost>,
                                   :localport(3333) );
loop {
    my $conn = $listen.accept;
    try {
        while my $buf = $conn.recv() {
            put now - (EVAL $buf)[1] - 37;  # also subtract leap seconds
            EVALFILE (EVAL $buf)[0];
        }
    }
    $conn.close;
    CATCH { default {.payload.say} }
}
Run Code Online (Sandbox Code Playgroud)

ra,轻客户端:

                                      Virtual size  Resident set size

raku -e 'loop {sleep 1}'                    146704  107200

perl -e 'while (1) {sleep 1}'                 1252    4036

sh -c 'while true; do sleep 1; done'           892     900

#include <unistd.h>
void main(void) { for(;;) {sleep(1);} }        172     780
Run Code Online (Sandbox Code Playgroud)

/tmp/test.raku

put "Hello, World!";
run 'notify-send', 'Hello, World!'
Run Code Online (Sandbox Code Playgroud)

raku-persistent在一个终端中一次;
ra [script.raku]在另一个终端,你想要多少次。

延迟范围 0.008848472 - 1.322056732;大多数情况下低于 0.07。0.008848472一定是某种错误——它比perl启动时间短,这是不可能的。

这仍然是一个概念证明,因为参数不会进入目标脚本。


更新2:

作为对/sf/answers/5174323871/的反应

建议的工作台套件在我的机器上不起作用Makefile,即使在基于 Debian 的 antiX 21 上也是如此,在我半手动完成所有测量后找到了可能的解决方案。而且,在 OpenBSD 上甚至run.c 无法编译。由于零基础c,我求助于 shell time for i in $(seq 1000); do ./<file> >/dev/null; done
所有 4 台机器都有 HDD,没有 SSD。
我的初始配置是 i5-3320M OpenBSD 并标记为^. 1K 次调用的结果
为单位,也适用于仅 Raku 的单次调用

 CPU           cores  GHz  OS            via         Raku K     Raku 1    Perl K  C K
 Pentium 4-M i686  1  2.2  OpenBSD i386  shell seq   36m32.479  2.192479  22.368  6.408
 Core 2 Duo T5800  2  2    antiX         c run       10m34.460  0.63446    2.224  0.535
 Core 2 Duo T5800  2  2    antiX         shell seq    7m48.153  0.468153   3.878  1.509
^i5-3320M          2  2.6  OpenBSD       shell seq    8m 0.011  0.480011   8.150  2.258
 i5-3320M          2  2.6  antiX live    c run        4m53.469  0.293469   1.157  0.276
 i5-3320M          2  2.6  antiX live    shell seq    3m37.042  0.217042   1.688  0.615
 i7-3770S          4  3.1  OpenBSD       shell seq    6m44.920  0.40492    7.026  2.340
 i7-3770S          4  3.1  antiX live    c run        4m 5.571  0.245571   0.872  0.268
Run Code Online (Sandbox Code Playgroud)

一些亮点:

  • 无论 CPU 和操作系统如何,Raku 启动时间都不受欢迎
  • 对于 Perl 和 C,shellfor i in $(seq...比自定义 C 慢,但对于 Raku,其性能优于它 - 在 Core 2 Duo 上为 7m+ vs 10m+,在 i5 上为 3m+ vs 4m+run
  • OpenBSD 并不优先考虑速度
  • 3rd-party 软件不优先考虑针对 OpenBSD 的优化

Eli*_*sen 5

假设您有最新版本的 Rakudo,我可以说您的机器确实非常慢:

% time perl -E 'say "Hello, World!"'
Hello, World!
real    0.05s
user    0.00s
sys 0.03s

% time raku -e 'put "Hello, World!"'
Hello, World!
real    0.12s
user    0.12s
sys 0.02s
Run Code Online (Sandbox Code Playgroud)

这是我在使用了 2 年的 M1 MacMini 上看到的数字。在运行 Debian 的 10 多年前的 MacMini 上,我看到:

$ time perl -E 'say "Hello, World!"'
Hello, World!

real    0m0.009s
user    0m0.004s
sys 0m0.005s

$ time raku -e 'put "Hello, World!"'
Hello, World!

real    0m0.241s
user    0m0.287s
sys 0m0.041s
Run Code Online (Sandbox Code Playgroud)

现在回到你的问题:是的,你可以有像 FastCGI 这样的东西,但对于本地 shell:

% raku -e 'while prompt "Enter filename: " -> $filename { EVALFILE $filename }
Run Code Online (Sandbox Code Playgroud)

运行它,输入要执行的脚本的名称并按 ENTER,它将运行。现在,这就是原则:这只运行不带参数的脚本。您可以在此基础上允许争论等。

  • OpenBSD 7.1 amd64、ThinkPad T530、2012 年制造、HDD(不是 SSD)、i5-3320M、16GB RAM - 您认为它应该比 500+ millis 性能更高吗? (2认同)

cod*_*ons 5

您描述的客户端-服务器模型对我来说似乎是一个非常好的主意!事实上,我自己也一直在考虑类似的想法。事实上,我在 2022 年 Perl 和 Raku 会议上就这个主题做了一次闪电般的演讲,A Nailgun for Raku

\n

正如该演讲提到的,这是Nailgun \xe2\x80\x93背后的基本思想,它实现了相同的思想,但针对 Java。正如您所注意到的,它比概念验证要复杂一些,但看起来绝对是一个可行的 Raku 项目。

\n

另一方面,我同意 Raiph [编辑:和 Liz,哎呀!] 的观点,即就启动速度而言,您发布的时间非常接近最坏情况。我的语言启动时间基准参考是bdrung/startup-time,它既有基准测试框架又有作者自己的数据。为了进行比较,该作者记录了“Hello, World!” C 程序在 0.26 毫秒(对于 2018 年笔记本电脑)和 2.19 毫秒(对于 Raspberry Pi 3)之间。这些时间可能会为您测量的“Hello, World!”5.03 到 7.67 毫秒的时间提供一些背景信息。C 程序。

\n