Skip to content

Commit 66cca81

Browse files
committed
Benchmark parallel-letter-frequency. Closes exercism#244
1 parent 3bf514e commit 66cca81

File tree

9 files changed

+120
-34
lines changed

9 files changed

+120
-34
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ env:
1313
- DENYWARNINGS=
1414
- DENYWARNINGS=1
1515
matrix:
16+
include:
17+
- rust: nightly
18+
env: BENCHMARK=1
19+
script: "./_test/check-exercises.sh"
1620
allow_failures:
1721
- rust: nightly
1822
- rust: beta

_test/check-exercises.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@ if [ -z "$DENYWARNINGS" ]; then
66
set -e
77
fi
88

9+
if [ -n "$BENCHMARK" ]; then
10+
files=exercises/*/benches
11+
else
12+
files=exercises/*/tests
13+
fi
14+
915
tmp=${TMPDIR:-/tmp/}
1016
mkdir "${tmp}exercises"
1117

1218
exitcode=0
1319

1420
# An exercise worth testing is defined here as any top level directory with
1521
# a 'tests' directory
16-
for exercise in exercises/*/tests; do
22+
for exercise in $files; do
1723
# This assumes that exercises are only one directory deep
1824
# and that the primary module is named the same as the directory
1925
directory=$(dirname "${exercise}");
@@ -38,7 +44,10 @@ for exercise in exercises/*/tests; do
3844
sed -i '/\[ignore\]/d' $test
3945
done
4046

41-
if [ -n "$DENYWARNINGS" ]; then
47+
# Run benchmarks in instead when enabled.
48+
if [ -n "$BENCHMARK" ]; then
49+
cargo bench
50+
elif [ -n "$DENYWARNINGS" ]; then
4251
sed -i -e '1i #![deny(warnings)]' src/lib.rs
4352

4453
# No-run mode so we see no test output.

exercises/parallel-letter-frequency/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[package]
22
name = "parallel-letter-frequency"
33
version = "0.0.0"
4+
5+
[dev-dependencies]
6+
sequential-letter-frequency = { path = "sequential-letter-frequency" }
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![feature(test)]
2+
extern crate parallel_letter_frequency;
3+
extern crate sequential_letter_frequency;
4+
extern crate test;
5+
6+
use sequential_letter_frequency::*;
7+
use test::Bencher;
8+
9+
#[bench]
10+
fn bench_sequential(b: &mut Bencher) {
11+
let texts = all_texts();
12+
b.iter(|| sequential_letter_frequency::frequency(&texts));
13+
}
14+
15+
#[bench]
16+
fn bench_parallel(b: &mut Bencher) {
17+
let texts = all_texts();
18+
b.iter(|| parallel_letter_frequency::frequency(&texts, 3));
19+
}
20+
21+
fn all_texts() -> Vec<&'static str> {
22+
[ODE_AN_DIE_FREUDE, WILHELMUS, STAR_SPANGLED_BANNER]
23+
.iter()
24+
.flat_map(|anthem| anthem.iter().cloned())
25+
.collect()
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!**src
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[package]
2+
name = "sequential-letter-frequency"
3+
version = "0.0.0"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::collections::HashMap;
2+
3+
/// Simple sequential char frequency. Can it be beat?
4+
pub fn frequency(texts: &[&str]) -> HashMap<char, usize> {
5+
let mut map = HashMap::new();
6+
7+
for line in texts {
8+
for chr in line.chars().filter(|c| c.is_alphabetic()) {
9+
if let Some(c) = chr.to_lowercase().next() {
10+
(*map.entry(c).or_insert(0)) += 1;
11+
}
12+
}
13+
}
14+
15+
map
16+
}
17+
18+
// Poem by Friedrich Schiller. The corresponding music is the European Anthem.
19+
pub const ODE_AN_DIE_FREUDE: [&'static str; 8] = [
20+
"Freude schöner Götterfunken",
21+
"Tochter aus Elysium,",
22+
"Wir betreten feuertrunken,",
23+
"Himmlische, dein Heiligtum!",
24+
"Deine Zauber binden wieder",
25+
"Was die Mode streng geteilt;",
26+
"Alle Menschen werden Brüder,",
27+
"Wo dein sanfter Flügel weilt."];
28+
29+
// Dutch national anthem
30+
pub const WILHELMUS: [&'static str; 8] = [
31+
"Wilhelmus van Nassouwe",
32+
"ben ik, van Duitsen bloed,",
33+
"den vaderland getrouwe",
34+
"blijf ik tot in den dood.",
35+
"Een Prinse van Oranje",
36+
"ben ik, vrij, onverveerd,",
37+
"den Koning van Hispanje",
38+
"heb ik altijd geëerd."];
39+
40+
// American national anthem
41+
pub const STAR_SPANGLED_BANNER: [&'static str; 8] = [
42+
"O say can you see by the dawn's early light,",
43+
"What so proudly we hailed at the twilight's last gleaming,",
44+
"Whose broad stripes and bright stars through the perilous fight,",
45+
"O'er the ramparts we watched, were so gallantly streaming?",
46+
"And the rockets' red glare, the bombs bursting in air,",
47+
"Gave proof through the night that our flag was still there;",
48+
"O say does that star-spangled banner yet wave,",
49+
"O'er the land of the free and the home of the brave?"];

exercises/parallel-letter-frequency/tests/parallel-letter-frequency.rs

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,9 @@
11
use std::collections::HashMap;
22

33
extern crate parallel_letter_frequency as frequency;
4+
extern crate sequential_letter_frequency;
45

5-
// Poem by Friedrich Schiller. The corresponding music is the European Anthem.
6-
const ODE_AN_DIE_FREUDE: [&'static str; 8] = [
7-
"Freude schöner Götterfunken",
8-
"Tochter aus Elysium,",
9-
"Wir betreten feuertrunken,",
10-
"Himmlische, dein Heiligtum!",
11-
"Deine Zauber binden wieder",
12-
"Was die Mode streng geteilt;",
13-
"Alle Menschen werden Brüder,",
14-
"Wo dein sanfter Flügel weilt."];
15-
16-
// Dutch national anthem
17-
const WILHELMUS: [&'static str; 8] = [
18-
"Wilhelmus van Nassouwe",
19-
"ben ik, van Duitsen bloed,",
20-
"den vaderland getrouwe",
21-
"blijf ik tot in den dood.",
22-
"Een Prinse van Oranje",
23-
"ben ik, vrij, onverveerd,",
24-
"den Koning van Hispanje",
25-
"heb ik altijd geëerd."];
26-
27-
// American national anthem
28-
const STAR_SPANGLED_BANNER: [&'static str; 8] = [
29-
"O say can you see by the dawn's early light,",
30-
"What so proudly we hailed at the twilight's last gleaming,",
31-
"Whose broad stripes and bright stars through the perilous fight,",
32-
"O'er the ramparts we watched, were so gallantly streaming?",
33-
"And the rockets' red glare, the bombs bursting in air,",
34-
"Gave proof through the night that our flag was still there;",
35-
"O say does that star-spangled banner yet wave,",
36-
"O'er the land of the free and the home of the brave?"];
6+
use sequential_letter_frequency::*;
377

388
#[test]
399
fn test_no_texts() {
@@ -121,3 +91,17 @@ fn test_all_three_anthems_3_workers() {
12191
assert_eq!(freqs.get(&'t'), Some(&56));
12292
assert_eq!(freqs.get(&'ü'), Some(&2));
12393
}
94+
95+
#[test]
96+
#[ignore]
97+
fn test_matches_sequential() {
98+
let mut v = Vec::new();
99+
for anthem in [ODE_AN_DIE_FREUDE, WILHELMUS, STAR_SPANGLED_BANNER].iter() {
100+
for line in anthem.iter() {
101+
v.push(*line);
102+
}
103+
}
104+
let freqs = frequency::frequency(&v[..], 3);
105+
let ref_freqs = sequential_letter_frequency::frequency(&v[..]);
106+
assert_eq!(freqs, ref_freqs);
107+
}

0 commit comments

Comments
 (0)