使用rust的rayon库函数。
1,rayon库函数优化代码:
fn build_merkle_tree(root: Arc<Mutex<Vec<usize>>>, vect:Vec<usize>, k: Arc<AtomicUsize>, p:usize,q:usize) {
let root_clone = Arc::clone(&root);
let k_clone = Arc::clone(&k);
let temp:Vec<_> = vect.par_chunks(2).enumerate().filter_map(|(i,vect_num)| {
let mut root_new = root_clone.lock().expect("出错了");
let i = i * 2;
if i == vect.len()-1 || i == vect.len() -2 {
let current_k = k_clone.fetch_add(1, Ordering::SeqCst);
if current_k>=p && current_k<=q {
root_new[current_k] = vect_num[0];
}
}
if i < vect.len()-1 {
return Some(Hash(vect_num[0],vect_num[1]))
} else {
return None;
}
}).collect();
if !temp.is_empty() {
build_merkle_tree( root, temp, k, p,q)
} else {
return ;
}
}
2,未使用多线程优化代码。
fn build_merkle_tree_two(root: &mut Vec<usize>, vect:&Vec<usize>, mut k: usize, p:usize,q:usize) -> usize{
if vect.len() == 0 {
return k;
}
let mut temp = Vec::new();
for i in (0..vect.len()).step_by(2) {
if i == vect.len()-1 || i == vect.len() -2 {
root[k] = vect[i];
k +=1;
}
if i < vect.len()-1 {
temp.push(Hash(vect[i],vect[i+1]));
}
}
k = build_merkle_tree_two( root, &temp, k, 0,0);
return k;
}
1
共 4 条评论, 1 页
评论区
写评论问题已经被指出来了,就是:
虽然在你现有代码上,可以严格限制锁周期来缓解性能问题,但是我没太懂,你调用方是需要
root
的完整数据用来做什么吗。不清楚你传的初始
root
和k
是什么,以及你想要利用参数传值的方式在调用方使用root
里什么数据, 不过因为你用的Vec<..>
结构很明显在并行任务里因为共享问题严重限制了并行度 。所以优化方式只能是拆解
root
结构,尽可能让并行任务不要彼此互斥加锁。简单解读你的代码,看着不像是想要返回构建完整的默克尔树节点的,如果你只是需要根值的话,root就感觉没必要了。建议使用
return
的方式返回值,而不是在参数里返回,可能有助于你更好的拆解任务--
👇
zhu-zk:
大佬,可以帮忙修改一下代码吗,非常感谢。
--
👇
xiaoyaou: 虽然不了解默克尔数的具体细节,但是你写的并行计算,显然因为每个任务都需要独占唯一的
root: Arc<Mutex<..>>
锁,所以并的并不是很行[doge]
虽然不了解默克尔数的具体细节,但是你写的并行计算,显然因为每个任务都需要独占唯一的
root: Arc<Mutex<..>>
锁,所以并的并不是很行[doge]