Reputation: 514
I'd like to perform some benchmarks over a range of functions that should be bench marked individually. So I thought I could define a macro that would generate all the functions.
The output for the range 1..10
should look something like this:
#[bench]
fn bench1(b: &mut Bencher) { b.iter(|| { test_function(1) }); }
#[bench]
fn bench2(b: &mut Bencher) { b.iter(|| { test_function(2) }); }
#[bench]
fn bench3(b: &mut Bencher) { b.iter(|| { test_function(3) }); }
#[bench]
fn bench4(b: &mut Bencher) { b.iter(|| { test_function(4) }); }
#[bench]
fn bench5(b: &mut Bencher) { b.iter(|| { test_function(5) }); }
#[bench]
fn bench6(b: &mut Bencher) { b.iter(|| { test_function(6) }); }
#[bench]
fn bench7(b: &mut Bencher) { b.iter(|| { test_function(7) }); }
#[bench]
fn bench8(b: &mut Bencher) { b.iter(|| { test_function(8) }); }
#[bench]
fn bench9(b: &mut Bencher) { b.iter(|| { test_function(9) }); }
First I don't know how I can generate the function name bench$n
in the macro.
The next problem that I'm facing is that the number should be an ident and an expr at the same time, this is because I need to use the same argument in the function name and in the expression for test_function
. I also thought about an recursive approach to the macro but I really never used macros in Rust before.
How if possible would one implement this macro.
Upvotes: 1
Views: 165
Reputation: 2507
A combination of the duplicate
and paste
crates can get you some of what you are looking for:
use duplicate::duplicate_item;
use paste::paste;
#[duplicate_item(
num; [1]; [2]; [3]; [4]; [5]; [6]; [7]; [8]; [9];
)]
paste!{
#[bench]
fn [< bench num >](b: &mut Bencher) { b.iter(|| { test_function(num) });}
}
The above code will expand to your exact code.
duplicate_item
makes sure to duplicate the function for each integer value you want, while paste
can concatenate the number with bench
to generate each function's name.
This will not work using an explicit range like 1..10
, as duplicate_item
needs to be given each value individually. But as long as your range is manageably small it should be fine. Alternatively, it can also work if you want individual values that don't necessarily follow each other.
Upvotes: 1