以下是最小值(?)我的代码的可复制示例.这是WIP Raku模块Dan::Polars压力测试/基准测试的第一关.

在《铁 rust 》中,我制作了一个libmre.所以用这个代码

  1 use libc::c_char;
  2 use libc::size_t;
  3 use std::slice;
  4 use std::ffi::*; //{CStr, CString,}
  5 
  6 //  Container
  7 
  8 pub struct VecC {
  9     ve: Vec::<String>,
 10 }   
 11 
 12 impl VecC {
 13     fn new(data: Vec::<String>) -> VecC               
 14     {   
 15         VecC {
 16             ve: data,
 17         }   
 18     }   
 19     
 20     fn show(&self) {
 21         println!{"{:?}", self.ve};
 22     }   
 23 }   
 24     
 25 #[no_mangle]
 26 pub extern "C" fn ve_new_str(ptr: *const *const c_char, len: size_t)                        
 27     -> *mut VecC {    
 28     
 29     let mut ve_data = Vec::<String>::new();
 30     unsafe {
 31         assert!(!ptr.is_null());
 32         
 33         for item in slice::from_raw_parts(ptr, len as usize) {
 34             ve_data.push(CStr::from_ptr(*item).to_string_lossy().into_owned());
 35         };  
 36     };  
 37     
 38     Box::into_raw(Box::new(VecC::new(ve_data)))
 39 }   
 40 
 41 #[no_mangle]
 42 pub extern "C" fn ve_show(ptr: *mut VecC) {
 43     let ve_c = unsafe {
 44         assert!(!ptr.is_null());
 45         &mut *ptr
 46     };  
 47     
 48     ve_c.show();
 49 }  

还有这批货.汤姆

  1 [package]
  2 name = "mre"
  3 version = "0.1.0"
  4 edition = "2021"
  5 
  6 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
  7 
  8 [dependencies]
  9 libc = "0.2.126"
 10 
 11 [lib]
 12 name = "mre"
 13 path = "src/lib.rs"
 14 crate-type = ["cdylib"]

在拉库,我消费libmre.就像这样

  1 #!/usr/bin/env raku
  2 use lib '../lib';
  3 
  4 use NativeCall;
  5 
  6 #my $output;    #mre tried to move decl to here to avoid going out of scope
  7 sub carray( $dtype, @items ) {
  8     my $output := CArray[$dtype].new();
  9     loop ( my $i = 0; $i < @items; $i++ ) {
 10         $output[$i] = @items[$i]
 11     }
 12     say $output;
 13     $output
 14 }   
 15     
 16 ### Container Classes that interface to Rust lib.rs ###
 17 
 18 constant $n-path    = '../mre/target/debug/mre';
 19 
 20 class VecC is repr('CPointer') is export {
 21     sub ve_new_str(CArray[Str],size_t) returns VecC is native($n-path) { * }
 22     sub ve_show(VecC) is native($n-path) { * }
 23     
 24     method new(@data) { 
 25         ve_new_str(carray(Str, @data), @data.elems );
 26     }   
 27     
 28     method show {
 29         ve_show(self)
 30     }   
 31 }   
 32 
 33 my \N = 100;   #should be 2e9  #fails between 30 and 100
 34 my \K = 100;   
 35 
 36 sub randChar(\f, \numGrp, \N) {
 37     my @things = [sprintf(f, $_) for 1..numGrp];
 38     @things[[1..numGrp].roll(N)];
 39 }   
 40 
 41 my @data = [randChar("id%03d", K, N)];
 42 
 43 my $vec = VecC.new( @data );
 44 $vec.show;

当\N为&lt;30这样的输出运行良好:

NativeCall::Types::CArray[Str].new
["id098", "id035", "id024", "id067", "id051", "id025", "id024", "id092", "id044", "id042", "id033", "id004", "id100", "id091", "id087", "id059", "id031", "id063", "id019", "id035"]

当\N为&gt;50然而,我得到:

NativeCall::Types::CArray[Str].new
Segmentation fault (core dumped)

这是:

Welcome to Rakudo™ v2022.04.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.04.
on ubuntu

由于基准要求为2e9,我可以使用一些帮助来try 解决这个问题.

如果您想在家试用,欢迎在Docker Hub上使用p6steve/raku-dan:polars-2022.02-arm64(或-amd64).别忘了第一次go cargo build.这包括RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y

推荐答案

randChar函数中有off by one个错误

sub randChar(\f, \numGrp, \N) {
    my @things = [sprintf(f, $_) for 1..numGrp];     
    @things[[1..numGrp].roll(N)];
}   

您正在用1numGrp的索引索引@things数组,但@things的最大索引是numGrp - 1.所以有时候返回数组的一个(或多个)元素中有(Any)而不是字符串.

你想要的是:

sub randChar(\f, \numGrp, \N) {
    my @things = [sprintf(f, $_) for 1..numGrp];     
    @things.roll(N); # call roll directly on @things
}   

Rust相关问答推荐

将已知大小的切片合并成一个数组,

PyReadonlyArray2到Vec T<>

重写Rust中的方法以使用`&;mut self`而不是`mut self`

为什么基于高山Linux的Docker镜像不能在绝对路径下找到要执行的命令?

为什么特征默认没有调整大小?

如何迭代存储在 struct 中的字符串向量而不移动它们?

当没有实际结果时,如何在 Rust 中强制执行错误处理?

为什么Rust编译器会忽略模板参数应具有静态生命周期?

没有明确地说return会产生错误:match arms have incompatible types

如果不满足条件,如何在 Rust 中引发错误

当你删除一个存在于堆栈中的值时,为什么 rust 不会抱怨

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

为什么具有 Vec 变体的枚举没有内存开销?

使用部分键从 Hashmap 中检索值

为实现特征的所有类型实现显示

在 Rust 中退出进程

在 Rust 中组合特征的不同方法是否等效?

为什么 `ref` 会导致此示例*取消引用*一个字段?

为什么在使用 self 时会消耗 struct 而在解构时不会?

类型参数不受 impl 特征、自身类型或谓词的约束