在上文中:
Rust: 量化策略回测与简易线程池构建、子线程执行观测
是自定义的线程池的方案。下面介绍一下用三方库Rayon的方案。

一、主要技术要点

1、策略封装

具体见上文。

2、Rayon的用法
涉及到线程池的设置,以及并发函数的调用。
线程池:

    let pool = rayon::ThreadPoolBuilder::new()
    .num_threads(3)
    .build()
    .unwrap();

还有并发函数:par_bridge()等使用。
其中,par_bridge() 从顺序迭代器创建并行迭代器。不开的话,还是可能是单线程运行。

二、具体代码

1、toml设置如下:

[dependencies]
rayon = "1.11.0"

2、具体代码如下:

use std::thread;
use std::time::{Duration,Instant};
#[derive(Debug,Clone)]
enum Parameter{
    P0(()),
    P1(f32,f32),
    P2(f32,f32,f32),
    P3(f32,f32,f32,f32),
}
#[derive(Debug,Clone,PartialEq)]
enum OutPut{
    TradeFlow0(f32),
    TradeFlow1(Vec<f32>,Vec<f32>),
    TradeFlow2(Vec<f32>),
}
type Job = Box<dyn FnOnce() -> OutPut + Send +'static >;
fn strategy_follow_trend(p:Parameter) ->OutPut{
    println!("run 【follow_trend】 strategy {:?}",p);
    thread::sleep(Duration::from_secs(1));
    OutPut::TradeFlow1(vec![1.0,2.0,3.0],vec![4.0,5.0,6.0])
    
}
fn strategy_bolling(p:Parameter) -> OutPut{
    println!("run 【bolling】 strategy {:?}",p);
    thread::sleep(Duration::from_secs(1));
    OutPut::TradeFlow2(vec![1.0,2.0,3.0])
    
}
fn strategy_high_freq(p:Parameter)->OutPut{
    println!("run 【high_freq】 strategy {:?}",p);
    thread::sleep(Duration::from_secs(1));
    OutPut::TradeFlow0(0.0)
    
}

fn get_strategies() -> Vec<Job>{
    let p1 = Parameter::P1(2.0,3.0);
    let s1: Job  = Box::new(move || strategy_follow_trend(p1));
    let p2 = Parameter::P2(2.0,3.0,4.0);
    let s2: Job  = Box::new(move || strategy_bolling(p2));
    let p3 = Parameter::P0(());
    let s3: Job  = Box::new(move || strategy_high_freq(p3));
    let p4 = Parameter::P0(());
    let s4: Job  = Box::new(move || strategy_high_freq(p4));
    let p5 = Parameter::P1(2.0,3.0);
    let s5: Job  = Box::new(move || strategy_follow_trend(p5));
    let p6 = Parameter::P2(2.0,3.0,4.0);
    let s6: Job  = Box::new(move || strategy_bolling(p6));
    let p7 = Parameter::P0(());
    let s7: Job  = Box::new(move || strategy_high_freq(p7));
    let p8 = Parameter::P0(());
    let s8: Job  = Box::new(move || strategy_high_freq(p8));
    let strategies:Vec<Job> = vec![s1,s2,s3,s4,s5,s6,s7,s8];
    strategies
}

fn main(){
    
    rayon_run();
}

fn rayon_run(){
    use rayon::prelude::*;
    println!("rayon_run");
    let strategies = get_strategies();
    //let len = strategies.len();
    let start = Instant::now();
    let pool = rayon::ThreadPoolBuilder::new()
    .num_threads(3)
    .build()
    .unwrap();

    pool.install(|| {
        strategies.into_iter().enumerate().par_bridge().for_each(|(i,strategy)   | {
            println!("thread {:?} => strategy:{:?}",  std::thread::current().id(),i);
            strategy();
        });
    });

    let duration = start.elapsed();
    println!("run duration : {:?}",duration);
}

三、输出结果

rayon_run
thread ThreadId(3) => strategy:0
run 【follow_trend】 strategy P1(2.0, 3.0)
thread ThreadId(4) => strategy:2
run 【high_freq】 strategy P0(())
thread ThreadId(2) => strategy:1
run 【bolling】 strategy P2(2.0, 3.0, 4.0)
thread ThreadId(2) => strategy:3
run 【high_freq】 strategy P0(())
thread ThreadId(3) => strategy:5
run 【bolling】 strategy P2(2.0, 3.0, 4.0)
thread ThreadId(4) => strategy:4
run 【follow_trend】 strategy P1(2.0, 3.0)
thread ThreadId(2) => strategy:6
run 【high_freq】 strategy P0(())
thread ThreadId(3) => strategy:7
run 【high_freq】 strategy P0(())
run duration : 3.0033154s

总体上看,和自定义的线程效果基本一致。

其中,8个策略,3线程分配如下:
线程3:实施了3个策略
线程2:实施了3个策略
线程4:实施了2个策略
谨供参考。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐