Added profiling target with perf
authorJustin Worthe <justin@worthe-it.co.za>
Mon, 14 May 2018 19:51:36 +0000 (21:51 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Mon, 14 May 2018 19:51:36 +0000 (21:51 +0200)
Cargo.toml
Makefile [new file with mode: 0644]
src/bin/perf-test.rs [new file with mode: 0644]
src/main.rs
src/strategy/monte_carlo.rs
src/strategy/sample.rs

index 01abf5d..86a4b95 100644 (file)
@@ -16,4 +16,10 @@ lazy_static = "1.0"
 
 [[bench]]
 name = "engine"
-harness = false
\ No newline at end of file
+harness = false
+
+[profile.release]
+debug = true
+
+[features]
+benchmarking = []
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..10aff98
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+build:
+       cargo build --release
+
+test:
+       cargo test --release
+
+profile:
+       cargo build --release --features "benchmarking"
+       sudo perf record -F 99 -a -g target/release/perf-test
+       sudo perf script > out.perf
+       ../FlameGraph/stackcollapse-perf.pl out.perf > out.folded
+       ../FlameGraph/flamegraph.pl out.folded > flamegraph.svg
+
+clean:
+       cargo clean
+
+
+.PHONY: build test profile clean
diff --git a/src/bin/perf-test.rs b/src/bin/perf-test.rs
new file mode 100644 (file)
index 0000000..1397cc3
--- /dev/null
@@ -0,0 +1,53 @@
+extern crate zombot;
+extern crate time;
+use time::{PreciseTime, Duration};
+
+use zombot::*;
+use zombot::engine::command::Command;
+
+use std::error::Error;
+
+const STATE_PATH: &str = "init_state.json";
+
+const COMMAND_PATH: &str = "command.txt";
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::process;
+
+fn choose_move(settings: &engine::settings::GameSettings, state: &engine::GameState, start_time: &PreciseTime) -> Command {
+    let max_time = Duration::milliseconds(9950);
+    strategy::monte_carlo::choose_move(settings, state, start_time, max_time)
+}
+
+
+fn write_command(filename: &str, command: Command) -> Result<(), Box<Error> > {
+    let mut file = File::create(filename)?;
+    write!(file, "{}", command)?;
+    Ok(())
+}
+
+
+fn main() {
+    let start_time = PreciseTime::now();
+    
+    println!("Reading in state.json file");
+    let (settings, state) = match json::read_state_from_file(STATE_PATH) {
+        Ok(ok) => ok,
+        Err(error) => {
+            println!("Error while parsing JSON file: {}", error);
+            process::exit(1);
+        }
+    };
+    let command = choose_move(&settings, &state, &start_time);
+
+    match write_command(COMMAND_PATH, command) {
+        Ok(()) => {}
+        Err(error) => {
+            println!("Error while writing command file: {}", error);
+            process::exit(1);
+        }
+    }
+
+    println!("Elapsed time: {}", start_time.to(PreciseTime::now()));
+}
index 3d3d980..651df35 100644 (file)
@@ -1,6 +1,6 @@
 extern crate zombot;
 extern crate time;
-use time::PreciseTime;
+use time::{PreciseTime, Duration};
 
 use zombot::*;
 use zombot::engine::command::Command;
@@ -16,7 +16,8 @@ use std::io::prelude::*;
 use std::process;
 
 fn choose_move(settings: &engine::settings::GameSettings, state: &engine::GameState, start_time: &PreciseTime) -> Command {
-    strategy::monte_carlo::choose_move(settings, state, start_time)
+    let max_time = Duration::milliseconds(1950);
+    strategy::monte_carlo::choose_move(settings, state, start_time, max_time)
 }
 
 
index 86960eb..7e62cae 100644 (file)
@@ -8,12 +8,8 @@ const MAX_MOVES: u16 = 400;
 
 use time::{Duration, PreciseTime};
 
-// TODO Round start time here
-pub fn choose_move(settings: &GameSettings, state: &GameState, start_time: &PreciseTime) -> Command {
+pub fn choose_move(settings: &GameSettings, state: &GameState, start_time: &PreciseTime, max_time: Duration) -> Command {
     println!("Using MONTE_CARLO strategy");
-
-    //just under the max of 2 seconds, to avoid issues like overhead in the bot being run, and we still need to write the result of this to file
-    let max_time = Duration::milliseconds(1950);
     
     let mut rng = thread_rng();
     let mut command_scores = CommandScore::init_command_scores(settings, state);
@@ -27,8 +23,13 @@ pub fn choose_move(settings: &GameSettings, state: &GameState, start_time: &Prec
         }
     }
 
-    println!("{:#?}", command_scores);
     let command = command_scores.iter().max_by_key(|&c| c.win_ratio());
+
+    #[cfg(feature = "benchmarking")]
+    {
+        let total_iterations: u32 = command_scores.iter().map(|c| c.attempts).sum();
+        println!("Iterations: {}", total_iterations);
+    }
     
     match command {
         Some(ref command) => command.command,
index 72ab66c..2dad924 100644 (file)
@@ -1,11 +1,9 @@
 use engine;
 use engine::command::*;
 
-use time::PreciseTime;
-
 use rand::{thread_rng, Rng};
 
-pub fn choose_move(settings: &engine::settings::GameSettings, state: &engine::GameState, _start_time: &PreciseTime) -> Command {
+pub fn choose_move(settings: &engine::settings::GameSettings, state: &engine::GameState) -> Command {
     let mut rng = thread_rng();
     
     if state.player.can_afford_defence_buildings(settings) {