我无法使用Inline C将arrayrefs传递给C函数.我想请一些帮助.
首先,为了证明我可以让Inline C工作,我会将标量值传递给C函数:
#!/usr/bin/perl -I.
#
# try1.pl
#
use Inline C;
my $c = 3.8;
foo( $c );
__END__
__C__
void foo( double c )
{
printf( "C = %f\n", c );
}
Run Code Online (Sandbox Code Playgroud)
并运行它:
% ./try1.pl
C = 3.800000
Run Code Online (Sandbox Code Playgroud)
现在做同样的事情,但使用arrayref:
#!/usr/bin/perl -I.
#
# try2.pl
#
use Inline C;
my @abc = (1.9, 2.3, 3.8);
foo( \@abc );
__END__
__C__
void foo( double *abc )
{
printf( "C = %f\n", abc[2] );
}
Run Code Online (Sandbox Code Playgroud)
运行:
% ./try2.pl
Undefined subroutine …
Run Code Online (Sandbox Code Playgroud) 我的问题与使用内联C代码有关:是否有必要使用内联堆栈函数(Inline_Stack_Vars)来传入和传出变量,或者在此上下文中是否适合仅修改变量?
为了显示生物序列数据,我需要显示两个对齐字符串之间的差异; 例如给出这两个字符串:
ATCAGAAA--GACATGGGCCAAAGATTAA-CAGTGGCCATTGACAGGA--
--CCCCAACTGACAGGGGGCAAAGATTAA-CAGTGGCCATTG---GGA--
Run Code Online (Sandbox Code Playgroud)
我想得到这个(第二个字符串中的匹配字符替换为'.'.
--.CCC..CT....G...G..........-............---...--
Run Code Online (Sandbox Code Playgroud)
我有很多序列(数百万的Illumina读数),所以转向内联:: c进行字符匹配.以下内联代码似乎工作正常(将第二个参数更改为add_matchchars函数):
#!/usr/bin/perl
use Inline C;
my($seq1,$seq2) = qw/ ATCAGAAA--GACATGGGCCAAAGATTAA-CAGTGGCCATTGACAGGA--
--CCCCAACTGACAGGGGGCAAAGATTAA-CAGTGGCCATTG---GGA-- /;
print $seq1,"\n";
print $seq2,"\n";
add_matchchars($seq1,$seq2);
print $seq2,"\n";
__END__
__C__
void add_matchchars(char *seq1, char *seq2) {
int seq1char;
int seq2char;
while(seq1char = *seq1++ , seq2char = *seq2++) {
if (seq1char == seq2char) {
*seq2--;
if (seq1char != '-') {
*seq2 = '.';
}
*seq2++;
}
//printf("%c-%c\n",seq1char,seq2char);
}
// printf("%s\n%s\n",seq1,seq2);
}
Run Code Online (Sandbox Code Playgroud)
但是1)它是否合理有效(是否有更聪明/更好的方式)?2)它会泄漏内存吗?
我使用Inline :: C制作了一个模块,并且注意到在主机MacOS和来宾Linux VM上运行该模块之间存在一些意外的性能差异。研究它是由于默认的C编译器标志不同。在MacOS上,它们似乎是:
-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -O3 -DVERSION=\"0.00\" -DXS_VERSION=\"0.00\"
Run Code Online (Sandbox Code Playgroud)
与Centos 7相比:
-fPIC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -O2 -DVERSION=\"0.00\" -DXS_VERSION=\"0.00\"
Run Code Online (Sandbox Code Playgroud)
我的代码的主要区别是O3 vs O2,因此我研究了Inline文档并使用:
use Inline (C => Config => ccflags => '-O3');
Run Code Online (Sandbox Code Playgroud)
要明确指定-O3
。好吧,结果是这样-O3 -O2
应用的,因此指定ccflag不会覆盖默认值,它只会在默认值之前添加,最终不会产生任何效果。任何知道默认值的来源和/或如何覆盖默认值以指定所需的优化级别的想法。
我一直在研究处理大量dna的perl程序.它输出然而究竟是什么,我需要花费更长的时间比我想用我NYTprof已经收窄主要问题领域是,增加了我的价值观一起循环.会使用inline :: C进行数学计算,使我的程序更快,还是应该接受速度并继续前进?还有另一种提高速度的方法吗?这是我的程序和它将运行的输入以及已经输入的默认值的可执行文件.
如何从 Haskell 的inline-c 中的C 块获取列表或数组?换句话说,如何在 C 中构建复杂数据并在 Haskell 中使用它。像这样的东西:
foo :: IO [Int]
foo = do
what? <- [C.block| <what?> {
ints = calloc(10, sizeof(int));
// ...
return <what?>;
} |]
return <what?>
Run Code Online (Sandbox Code Playgroud)
我可以用某种 Haskell 类型包装一个指针和一个大小,但我想在 Haskell 中使用列表,打印它,用 JSON 编码等。
我正在使用C代码库
typedef void(* wl_notify_func_t) (struct wl_listener *listener, void *data)
//...
struct wl_listener {
struct wl_list link;
wl_notify_func_t notify; //<-- I'd like to return this
};
Run Code Online (Sandbox Code Playgroud)
并使用了Haskell代码
type NotifyFuncT = FunPtr (Ptr C'WlListener -> Ptr () -> IO ())
initializeMyCtx = C.context $ C.baseCtx <> C.funCtx <> mempty {
C.ctxTypesTable = Data.Map.fromList [
(C.Struct "wl_listener", [t|C'WlListener|])
-- ...
, (C.TypeName "wl_notify_func_t", [t|NotifyFuncT|])
]
}
someHaskellFunction :: Ptr C'WlListener -> IO NotifyFuncT
someHaskellFunction ptrToWlListener = do
funPtr <- [C.block| wl_notify_func_t {return $(struct …
Run Code Online (Sandbox Code Playgroud) 我正在构建一个模块,它连接到相机,拍照,并将数据读入一个小提琴.所有这些都发生在Inline :: C命令中.使用PDL文档中的过程,我可以创建pdl *
并返回它.然而,相机可能无法拍照,在这种情况下,我希望0
按照通常的协议返回my $pic_pdl = $Camera->TakePicture or die "Failed to take image"
.这似乎意味着我将需要使用该Inline_Stack_Push
机制,但我不知道如何正确地将其pdl *
转换为SV*
.如果可能的话,我也想设置$!
错误代码.可以在Inline中完成吗?
我有一个大约100,000个元素的字符串数组.我需要迭代每个元素并用其他单词替换一些单词.这需要几秒钟的纯perl.我需要尽可能加快速度.我正在测试使用以下代码段:
use strict;
my $string = "This is some string. Its only purpose is for testing.";
for( my $i = 1; $i < 100000; $i++ ) {
$string =~ s/old1/new1/ig;
$string =~ s/old2/new2/ig;
$string =~ s/old3/new3/ig;
$string =~ s/old4/new4/ig;
$string =~ s/old5/new5/ig;
}
Run Code Online (Sandbox Code Playgroud)
我知道这实际上并没有替换测试字符串中的任何内容,但它仅用于速度测试.
我对Inline :: C寄予厚望.我之前从未与之合作,Inline::C
但在阅读了一下之后,我认为实施起来相当简单.但很显然,即使调用存根函数,它什么都不是很多慢.这是我测试过的片段:
use strict;
use Benchmark qw ( timethese );
use Inline 'C';
timethese(
5,
{
"Pure Perl" => \&pure_perl,
"Inline C" => \&inline_c
}
);
sub pure_perl { …
Run Code Online (Sandbox Code Playgroud) 我有一个用 C++ 编写的大型程序,并使用 Inline::CPP 从 Perl 执行。代码似乎使用了大量内存,所以我假设存在某种泄漏。我编写了以下代码来重现相同的问题,但要简单得多。当我循环代码 1,000,000 次以测试代码的性能时,我发现了泄漏。这个简单的 Perl 脚本使用 828MiB,而我的完整程序使用 1.3GiB。
我尝试了很多方法,例如在代码中使用SvREFCNT_dec
、newRV_noinc
、sv_free
和sv_2mortal
各种变量,但我一直无法降低内存使用量。
这是我的示例代码:
use Data::Dumper;
print Dumper test ();
use Inline 'CPP' => << 'CPP';
#include <array>
using namespace std;
AV *array_to_av (const array<int,3> &v)
{
AV *array = newAV ();
for (int i : v) {
av_push (array, newSViv (i));
}
return array;
}
SV *test_leak ()
{
HV *hash = newHV ();
AV *array1 = array_to_av ({1,2,3});
AV …
Run Code Online (Sandbox Code Playgroud) inline-c ×9
perl ×7
haskell ×2
performance ×2
arrayref ×1
c ×1
c++ ×1
ffi ×1
optimization ×1
pdl ×1
return-type ×1
xs ×1