Skip to content

Commit 10aa1c3

Browse files
committed
test: Add fannkuch-redux and fasta-redux shootout benchmarks
1 parent 9738c2a commit 10aa1c3

File tree

4 files changed

+322
-82
lines changed

4 files changed

+322
-82
lines changed

src/libcore/vec.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
1313
#[warn(non_camel_case_types)];
1414

15-
use container::{Container, Mutable};
15+
use cast::transmute;
1616
use cast;
17+
use container::{Container, Mutable};
1718
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
1819
use clone::Clone;
1920
use iter::BaseIter;
@@ -2137,6 +2138,7 @@ pub trait ImmutableCopyableVector<T> {
21372138
fn filtered(&self, f: &fn(&T) -> bool) -> ~[T];
21382139
fn rfind(&self, f: &fn(t: &T) -> bool) -> Option<T>;
21392140
fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
2141+
unsafe fn unsafe_get(&self, elem: uint) -> T;
21402142
}
21412143

21422144
/// Extension methods for vectors
@@ -2173,6 +2175,13 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
21732175
fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) {
21742176
partitioned(*self, f)
21752177
}
2178+
2179+
/// Returns the element at the given index, without doing bounds checking.
2180+
#[inline(always)]
2181+
unsafe fn unsafe_get(&self, elem: uint) -> T {
2182+
let (ptr, _): (*T, uint) = transmute(*self);
2183+
*ptr.offset(elem)
2184+
}
21762185
}
21772186

21782187
pub trait OwnedVector<T> {
@@ -2313,6 +2322,19 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
23132322
}
23142323
}
23152324

2325+
pub trait MutableVector<T> {
2326+
unsafe fn unsafe_set(&self, elem: uint, val: T);
2327+
}
2328+
2329+
impl<'self,T> MutableVector<T> for &'self mut [T] {
2330+
#[inline(always)]
2331+
unsafe fn unsafe_set(&self, elem: uint, val: T) {
2332+
let pair_ptr: &(*mut T, uint) = transmute(self);
2333+
let (ptr, _) = *pair_ptr;
2334+
*ptr.offset(elem) = val;
2335+
}
2336+
}
2337+
23162338
/**
23172339
* Constructs a vector from an unsafe pointer to a buffer
23182340
*
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use core::from_str::FromStr;
2+
use core::i32::range;
3+
use core::vec::MutableVector;
4+
5+
fn max(a: i32, b: i32) -> i32 {
6+
if a > b {
7+
a
8+
} else {
9+
b
10+
}
11+
}
12+
13+
#[inline(never)]
14+
fn fannkuch_redux(n: i32) -> i32 {
15+
let mut perm = vec::from_elem(n as uint, 0i32);
16+
let mut perm1 = vec::from_fn(n as uint, |i| i as i32);
17+
let mut count = vec::from_elem(n as uint, 0i32);
18+
let mut max_flips_count = 0i32, perm_count = 0i32, checksum = 0i32;
19+
20+
let mut r = n;
21+
loop {
22+
unsafe {
23+
while r != 1 {
24+
count.unsafe_set((r-1) as uint, r);
25+
r -= 1;
26+
}
27+
28+
// XXX: Need each2_mut.
29+
for vec::eachi_mut(perm) |i, perm_i| {
30+
*perm_i = perm1.unsafe_get(i);
31+
}
32+
33+
let mut flips_count: i32 = 0;
34+
let mut k: i32;
35+
loop {
36+
k = perm.unsafe_get(0);
37+
if k == 0 {
38+
break;
39+
}
40+
41+
let k2 = (k+1) >> 1;
42+
for range(0, k2) |i| {
43+
let (perm_i, perm_k_i) = {
44+
(perm.unsafe_get(i as uint),
45+
perm.unsafe_get((k-i) as uint))
46+
};
47+
perm.unsafe_set(i as uint, perm_k_i);
48+
perm.unsafe_set((k-i) as uint, perm_i);
49+
}
50+
flips_count += 1;
51+
}
52+
53+
max_flips_count = max(max_flips_count, flips_count);
54+
checksum += if perm_count % 2 == 0 {
55+
flips_count
56+
} else {
57+
-flips_count
58+
};
59+
60+
// Use incremental change to generate another permutation.
61+
loop {
62+
if r == n {
63+
println(checksum.to_str());
64+
return max_flips_count;
65+
}
66+
67+
let perm0 = perm1[0];
68+
let mut i: i32 = 0;
69+
while i < r {
70+
let j = i + 1;
71+
let perm1_j = { perm1.unsafe_get(j as uint) };
72+
perm1.unsafe_set(i as uint, perm1_j);
73+
i = j;
74+
}
75+
perm1.unsafe_set(r as uint, perm0);
76+
77+
let count_r = { count.unsafe_get(r as uint) };
78+
count.unsafe_set(r as uint, count_r - 1);
79+
if count.unsafe_get(r as uint) > 0 {
80+
break;
81+
}
82+
r += 1;
83+
}
84+
85+
perm_count += 1;
86+
}
87+
}
88+
}
89+
90+
#[fixed_stack_segment]
91+
fn main() {
92+
let n: i32 = FromStr::from_str(os::args()[1]).get();
93+
println(fmt!("Pfannkuchen(%d) = %d", n as int, fannkuch_redux(n) as int));
94+
}
95+

src/test/bench/shootout-fannkuchredux.rs

Lines changed: 0 additions & 81 deletions
This file was deleted.

0 commit comments

Comments
 (0)