Perl 停滞不前的日子:揭示 C 的隐藏力量

perl 停滞不前的日子:揭示 c 的隐藏力量

有时会发生意想不到的事情,必须与世界分享……这就是这样的情况。

最近,我开始尝试使用 perl 进行数据科学应用程序的工作流管理和低级代码的高级监督。在这种情况下,我为 perl 保留的一个角色是内存缓冲区的生命周期管理,使用 perl 应用程序“分配”内存缓冲区并在用 c、assembly、fortran 编写的计算组件和最好的隐藏宝石之间穿梭。 perl 世界,perl 数据语言。
perl 至少可以通过 3 种方式来分配内存缓冲区:

生成字节列表并使用 pack 函数将它们转换为字符串。 使用重复运算符 (x) 生成一个长度等于所需缓冲区大小减一的字符串(在 perl 中,字符串通过空字节终止,因此空字节补偿了我的一个 ).通过 inline 或 ffi::platypus 访问外部内存分配器库来分配缓冲区。

以下 perl 代码实现了这三种方法(packstringc 中的 malloc),并允许尝试不同的缓冲区大小、初始值和结果精度(通过对分配的多次迭代进行平均)惯例)

#!/home/chrisarg/perl5/perlbrew/perls/current/bin/perluse v5.38;use inline (    c         => 'data',    cc        => 'g++',    ld        => 'g++',    inc       => q{},      # replace q{} with anything else you need    ccflagsex => q{},      # replace q{} with anything else you need    lddlflags => join(        q{ },        $config::config{lddlflags},        q{ },              # replace q{ } with anything else you need    ),    libs => join(        q{ },        $config::config{libs},        q{ },              # replace q{ } with anything else you need    ),    myextlib => '');use benchmark qw(cmpthese);use getopt::long;my ($buffer_size, $init_value, $iterations);getoptions(    'buffer_size=i' => $buffer_size,    'init_value=s'  => $init_value,    'iterations=i'  => $iterations,) or die "usage: $0 --buffer_size  --init_value  --iterations n";my $init_value_byte = ord($init_value);my %code_snippets   = (    'string' => sub {        $init_value x ( $buffer_size - 1 );    },    'pack' => sub {        pack "c*", ( ($init_value_byte) x $buffer_size );    },    'c' => sub {        allocate_and_initialize_array( $buffer_size, $init_value_byte );    },);cmpthese( $iterations, %code_snippets );__data____c__#include #include #include sv* allocate_and_initialize_array(size_t length, short initial_value) {    // allocate memory for the array    char* array = (char*)malloc(length * sizeof(char));    char initial_value_byte = (char)initial_value;    if (array == null) {        fprintf(stderr, "memory allocation failedn");        exit(1);    }    // initialize each element with the initial_value    memset(array, initial_value_byte, length);    return newsvuv(ptr2uv(array));}

将脚本调用为:

./time_mem_alloc.pl -buffer_size=1000000 -init_value=a -iterations=20000

产生了令人惊讶的结果:

          rate   pack      c stringpack     322/s     --   -92%   -99%c       4008/s  1144%     --   -92%string 50000/s 15417%  1147%     --

使用 perl string 方法比 c 的性能高出 10 倍

不相信巨大的性能提升,并认为我正在处理 inline::c 中的错误,我用纯 c 重新编码了分配(添加命令行处理/计时等的常用修饰):

#include #include #include #include 

按照c代码中注释所说的那样调用c程序,
我得到了以下结果:

Time taken to allocate and initialize array: 0.000203 secondsInitializes per second: 4926.108374

实际上执行的数量级与 inline::c malloc/c 方法的等效分配相同。
在进一步研究这个问题后,我发现我所欣赏的 malloc 牺牲了内存分配的速度以换取通用性,并且有大量更快的内存分配器。看来 perl 正在为其字符串使用这样一个分配器,并在分配缓冲区的任务中击败了 c。

以上就是Perl 停滞不前的日子:揭示 C 的隐藏力量的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1457326.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
C++ 函数调用约定和栈帧管理的工程实践与性能优化
上一篇 2025年12月18日 09:36:31
C++ 函数库和标准模板库在大数据处理中的作用有哪些?
下一篇 2025年12月18日 09:36:41

相关推荐

发表回复

登录后才能评论
关注微信