Open
Description
Thanks for this wonderful project. In under 24h, never having written any Rust code before, I have achieved a 2.5x speedup of an objective function that is invoked by base::integrate().
FYI, here is the original function from package dfcrm ...
crmh = function(a,x,y,w,s) { ## posterior
v = exp(-a^2/2/s^2)
for (i in 1:length(x)) {
v = v * ((x[i]^exp(a))^y[i])*(((1-w[i]*x[i]^exp(a))^(1-y[i])))
}
return(v)
}
and here is my initial direct translation into Rust:
/// A Rust implementation of the dfcrm::crmh posterior,
/// which I hope will prove faster to integrate().
/// @export
#[extendr]
fn rcrmh(a: &[f64],
x: &[f64],
y: &[f64],
w: &[f64],
s: &[f64]) -> Robj {
// TODO: Assert that x, y and w all have same length?
let v = a.iter().map(|a| {
let mut v_ = (-0.5*a/s[0]).exp();
for i in 0 .. y.len() {
let p_i = x[i].powf(a.exp()); // 'power model' CRM
v_ = v_ * if y[i] == 0.0 { 1.0 - w[i] * p_i } else { p_i };
}
v_
});
v.collect_robj()
}
Speaking from the POV of the Rust novice, the sort of example I would find most helpful would show a cascade of performance improvements that start with 'elegant' or 'default' wrappings and proceed step-wise through a series of tuning steps that exploit language features like borrowing, etc. Alluding to equivalent constructs in C would help orient users who are familiar with performance-tuning tricks in that language.
Metadata
Metadata
Assignees
Labels
No labels