@@ -19,15 +19,21 @@ use core::prelude::*;
19
19
20
20
use getopts;
21
21
use sort;
22
+ use stats:: Stats ;
22
23
use term;
24
+ use time:: precise_time_ns;
23
25
24
26
use core:: comm:: { stream, SharedChan } ;
25
27
use core:: either;
26
28
use core:: io;
29
+ use core:: num;
27
30
use core:: option;
31
+ use core:: rand:: RngUtil ;
32
+ use core:: rand;
28
33
use core:: result;
29
34
use core:: task;
30
35
use core:: to_str:: ToStr ;
36
+ use core:: u64;
31
37
use core:: uint;
32
38
use core:: vec;
33
39
@@ -609,152 +615,146 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
609
615
}
610
616
}
611
617
612
- pub mod bench {
613
- use core::prelude::*;
614
-
615
- use core::num;
616
- use core::rand::RngUtil;
617
- use core::rand;
618
- use core::u64;
619
- use core::vec;
620
- use stats::Stats;
621
- use test::{BenchHarness, BenchSamples};
622
- use time::precise_time_ns;
623
-
624
- impl BenchHarness {
625
- /// Callback for benchmark functions to run in their body.
626
- pub fn iter(&mut self, inner:&fn()) {
627
- self.ns_start = precise_time_ns();
628
- let k = self.iterations;
629
- for u64::range(0, k) |_| {
630
- inner();
631
- }
632
- self.ns_end = precise_time_ns();
618
+ impl BenchHarness {
619
+ /// Callback for benchmark functions to run in their body.
620
+ pub fn iter(&mut self, inner:&fn()) {
621
+ self.ns_start = precise_time_ns();
622
+ let k = self.iterations;
623
+ for u64::range(0, k) |_| {
624
+ inner();
633
625
}
626
+ self.ns_end = precise_time_ns();
627
+ }
634
628
635
- pub fn ns_elapsed(&mut self) -> u64 {
636
- if self.ns_start == 0 || self.ns_end == 0 {
637
- 0
638
- } else {
639
- self.ns_end - self.ns_start
640
- }
629
+ pub fn ns_elapsed(&mut self) -> u64 {
630
+ if self.ns_start == 0 || self.ns_end == 0 {
631
+ 0
632
+ } else {
633
+ self.ns_end - self.ns_start
641
634
}
635
+ }
642
636
643
- pub fn ns_per_iter(&mut self) -> u64 {
644
- if self.iterations == 0 {
645
- 0
646
- } else {
647
- self.ns_elapsed() / self.iterations
648
- }
637
+ pub fn ns_per_iter(&mut self) -> u64 {
638
+ if self.iterations == 0 {
639
+ 0
640
+ } else {
641
+ self.ns_elapsed() / self.iterations
649
642
}
643
+ }
650
644
651
- pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
652
- self.iterations = n;
653
- debug!(" running benchmark for %u iterations",
654
- n as uint);
655
- f(self);
656
- }
645
+ pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
646
+ self.iterations = n;
647
+ debug!(" running benchmark for %u iterations",
648
+ n as uint);
649
+ f(self);
650
+ }
657
651
658
- // This is the Go benchmark algorithm. It produces a single
659
- // datapoint and always tries to run for 1s.
660
- pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
661
-
662
- // Rounds a number down to the nearest power of 10.
663
- fn round_down_10(n: u64) -> u64 {
664
- let mut n = n;
665
- let mut res = 1;
666
- while n > 10 {
667
- n = n / 10;
668
- res *= 10;
669
- }
670
- res
671
- }
652
+ // This is the Go benchmark algorithm. It produces a single
653
+ // datapoint and always tries to run for 1s.
654
+ pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
672
655
673
- // Rounds x up to a number of the form [1eX, 2eX, 5eX].
674
- fn round_up(n: u64) -> u64 {
675
- let base = round_down_10(n);
676
- if n < (2 * base) {
677
- 2 * base
678
- } else if n < (5 * base) {
679
- 5 * base
680
- } else {
681
- 10 * base
682
- }
656
+ // Rounds a number down to the nearest power of 10.
657
+ fn round_down_10(n: u64) -> u64 {
658
+ let mut n = n;
659
+ let mut res = 1;
660
+ while n > 10 {
661
+ n = n / 10;
662
+ res *= 10;
683
663
}
664
+ res
665
+ }
684
666
685
- // Initial bench run to get ballpark figure.
686
- let mut n = 1_u64;
687
- self.bench_n(n, f);
688
-
689
- while n < 1_000_000_000 &&
690
- self.ns_elapsed() < 1_000_000_000 {
691
- let last = n;
692
-
693
- // Try to estimate iter count for 1s falling back to 1bn
694
- // iterations if first run took < 1ns.
695
- if self.ns_per_iter() == 0 {
696
- n = 1_000_000_000;
697
- } else {
698
- n = 1_000_000_000 / self.ns_per_iter();
699
- }
700
-
701
- n = u64::max(u64::min(n+n/2, 100*last), last+1);
702
- n = round_up(n);
703
- self.bench_n(n, f);
667
+ // Rounds x up to a number of the form [1eX, 2eX, 5eX].
668
+ fn round_up(n: u64) -> u64 {
669
+ let base = round_down_10(n);
670
+ if n < (2 * base) {
671
+ 2 * base
672
+ } else if n < (5 * base) {
673
+ 5 * base
674
+ } else {
675
+ 10 * base
704
676
}
705
677
}
706
678
707
- // This is a more statistics-driven benchmark algorithm.
708
- // It stops as quickly as 50ms, so long as the statistical
709
- // properties are satisfactory. If those properties are
710
- // not met, it may run as long as the Go algorithm.
711
- pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
712
-
713
- let mut rng = rand::rng();
714
- let mut magnitude = 10;
715
- let mut prev_madp = 0.0;
679
+ // Initial bench run to get ballpark figure.
680
+ let mut n = 1_u64;
681
+ self.bench_n(n, f);
716
682
717
- loop {
718
- let n_samples = rng.gen_uint_range(50, 60);
719
- let n_iter = rng.gen_uint_range(magnitude,
720
- magnitude * 2);
683
+ while n < 1_000_000_000 &&
684
+ self.ns_elapsed() < 1_000_000_000 {
685
+ let last = n;
721
686
722
- let samples = do vec::from_fn(n_samples) |_| {
723
- self.bench_n(n_iter as u64, f);
724
- self.ns_per_iter() as f64
725
- };
687
+ // Try to estimate iter count for 1s falling back to 1bn
688
+ // iterations if first run took < 1ns.
689
+ if self.ns_per_iter() == 0 {
690
+ n = 1_000_000_000;
691
+ } else {
692
+ n = 1_000_000_000 / self.ns_per_iter();
693
+ }
726
694
727
- // Eliminate outliers
728
- let med = samples.median();
729
- let mad = samples.median_abs_dev();
730
- let samples = do vec::filter(samples) |f| {
731
- num::abs(*f - med) <= 3.0 * mad
732
- };
695
+ n = u64::max(u64::min(n+n/2, 100*last), last+1);
696
+ n = round_up(n);
697
+ self.bench_n(n, f);
698
+ }
699
+ }
733
700
734
- debug!(" %u samples, median %f, MAD =%f, %u survived filter",
735
- n_samples, med as float, mad as float,
736
- samples.len());
737
-
738
- if samples.len() != 0 {
739
- // If we have _any_ cluster of signal...
740
- let curr_madp = samples.median_abs_dev_pct();
741
- if self.ns_elapsed() > 1_000_000 &&
742
- (curr_madp < 1.0 ||
743
- num::abs(curr_madp - prev_madp) < 0.1) {
744
- return samples;
745
- }
746
- prev_madp = curr_madp;
747
-
748
- if n_iter > 20_000_000 ||
749
- self.ns_elapsed() > 20_000_000 {
750
- return samples;
751
- }
701
+ // This is a more statistics-driven benchmark algorithm.
702
+ // It stops as quickly as 50ms, so long as the statistical
703
+ // properties are satisfactory. If those properties are
704
+ // not met, it may run as long as the Go algorithm.
705
+ pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
706
+
707
+ let mut rng = rand::rng();
708
+ let mut magnitude = 10;
709
+ let mut prev_madp = 0.0;
710
+
711
+ loop {
712
+ let n_samples = rng.gen_uint_range(50, 60);
713
+ let n_iter = rng.gen_uint_range(magnitude,
714
+ magnitude * 2);
715
+
716
+ let samples = do vec::from_fn(n_samples) |_| {
717
+ self.bench_n(n_iter as u64, f);
718
+ self.ns_per_iter() as f64
719
+ };
720
+
721
+ // Eliminate outliers
722
+ let med = samples.median();
723
+ let mad = samples.median_abs_dev();
724
+ let samples = do vec::filter(samples) |f| {
725
+ num::abs(*f - med) <= 3.0 * mad
726
+ };
727
+
728
+ debug!(" %u samples, median %f, MAD =%f, %u survived filter",
729
+ n_samples, med as float, mad as float,
730
+ samples.len());
731
+
732
+ if samples.len() != 0 {
733
+ // If we have _any_ cluster of signal...
734
+ let curr_madp = samples.median_abs_dev_pct();
735
+ if self.ns_elapsed() > 1_000_000 &&
736
+ (curr_madp < 1.0 ||
737
+ num::abs(curr_madp - prev_madp) < 0.1) {
738
+ return samples;
752
739
}
740
+ prev_madp = curr_madp;
753
741
754
- magnitude *= 2;
742
+ if n_iter > 20_000_000 ||
743
+ self.ns_elapsed() > 20_000_000 {
744
+ return samples;
745
+ }
755
746
}
747
+
748
+ magnitude *= 2;
756
749
}
757
750
}
751
+ }
752
+
753
+ pub mod bench {
754
+ use core::prelude::*;
755
+
756
+ use core::vec;
757
+ use test::{BenchHarness, BenchSamples};
758
758
759
759
pub fn benchmark(f: &fn(&mut BenchHarness)) -> BenchSamples {
760
760
0 commit comments