
有时会发生意想不到的事情,必须与世界分享......这就是这样的情况。
最近,我开始尝试使用 perl 进行数据科学应用程序的工作流管理和低级代码的高级监督。在这种情况下,我为 perl 保留的一个角色是内存缓冲区的生命周期管理,使用 perl 应用程序“分配”内存缓冲区并在用 c、assembly、fortran 编写的计算组件和最好的隐藏宝石之间穿梭。 perl 世界,perl 数据语言。
perl 至少可以通过 3 种方式来分配内存缓冲区:
以下 perl 代码实现了这三种方法(pack、string 和 c 中的 malloc),并允许尝试不同的缓冲区大小、初始值和结果精度(通过对分配的多次迭代进行平均)惯例)
#!/home/chrisarg/perl5/perlbrew/perls/current/bin/perl
use 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 <size> --init_value <value> --iterations <count>\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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
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 failed\n");
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 string pack 322/s -- -92% -99% c 4008/s 1144% -- -92% string 50000/s 15417% 1147% --
使用 perl string 方法比 c 的性能高出 10 倍。
不相信巨大的性能提升,并认为我正在处理 inline::c 中的错误,我用纯 c 重新编码了分配(添加命令行处理/计时等的常用修饰):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char* allocate_and_initialize_array(size_t length, char initial_value) {
// allocate memory for the array
char* array = (char*)malloc(length * sizeof(char));
if (array == null) {
fprintf(stderr, "memory allocation failed\n");
exit(1);
}
// initialize each element with the initial_value
memset(array, initial_value, length);
return array;
}
double time_allocation_and_initialization(size_t length, char initial_value) {
clock_t start, end;
double cpu_time_used;
start = clock();
char* array = allocate_and_initialize_array(length, initial_value);
end = clock();
cpu_time_used = ((double) (end - start)) / clocks_per_sec;
/* this rudimentary loop prevents the compiler from optimizing out the
* allocation/initialization with the de-allocation
*/
for(size_t i = 1; i < length; i++) {
array[i]++;
if(i % 100000 == 0) {
printf("array[%zu] = %c\n", i, array[i]);
}
}
free(array); // free the allocated memory
return cpu_time_used;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "usage: %s <length> <initial_value>\n", argv[0]);
return 1;
}
size_t length = strtoull(argv[1], null, 10);
char initial_value = argv[2][0];
double time_taken = time_allocation_and_initialization(length, initial_value);
printf("time taken to allocate and initialize array: %f seconds\n", time_taken);
printf("initializes per second: %f\n", 1/time_taken);
return 0;
}
/*
compilation command:
gcc -o2 -o time_array_allocation time_array_allocation.c -std=c99
example invocation:
./time_array_allocation 10000000 a
*/
按照c代码中注释所说的那样调用c程序,
我得到了以下结果:
Time taken to allocate and initialize array: 0.000203 seconds Initializes per second: 4926.108374
实际上执行的数量级与 inline::c malloc/c 方法的等效分配相同。
在进一步研究这个问题后,我发现我所欣赏的 malloc 牺牲了内存分配的速度以换取通用性,并且有大量更快的内存分配器。看来 perl 正在为其字符串使用这样一个分配器,并在分配缓冲区的任务中击败了 c。
以上就是Perl 停滞不前的日子:揭示 C 的隐藏力量的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号