diff --git a/Cargo.lock b/Cargo.lock index bddde59..3d33644 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,24 @@ dependencies = [ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "backtrace" version = "0.3.9" @@ -27,6 +45,11 @@ dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" version = "1.0.25" @@ -37,6 +60,20 @@ name = "cfg-if" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "failure" version = "0.1.3" @@ -57,6 +94,14 @@ dependencies = [ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "heck" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyperjson" version = "0.2.0" @@ -141,8 +186,10 @@ dependencies = [ name = "profiling" version = "0.1.0" dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyperjson 0.2.0", "pyo3 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -188,6 +235,19 @@ dependencies = [ "proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "1.0.6" @@ -248,6 +308,31 @@ name = "spin" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.20" @@ -269,6 +354,24 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -282,6 +385,16 @@ name = "ucd-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-segmentation" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -292,6 +405,11 @@ name = "utf8-ranges" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "version_check" version = "0.1.5" @@ -318,12 +436,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" +"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" @@ -338,6 +461,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pyo3-derive-backend 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00927a5ccbbd44495eac7b35adef285d0a1b12667d1ca91ad14b7755f164abff" "checksum pyo3cls 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ea36d0569ee1961831db1646f949e4c2040cf8268c6ac6b290d8c4ec1e603cd" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" +"checksum redox_syscall 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "cf8fb82a4d1c9b28f1c26c574a5b541f5ffb4315f6c9a791fa47b6a04438fe93" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467" "checksum regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc557aac2b708fe84121caf261346cc2eed71978024337e42eb46b8a252ac6e" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" @@ -346,12 +471,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" "checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "41c4a2479a078509940d82773d90ff824a8c89533ab3b59cd3ce8b0c0e369c02" +"checksum structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5352090cfae7a2c85e1a31146268b53396106c88ca5d6ccee2e3fae83b6e35c2" "checksum syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)" = "8886c8d2774e853fcd7d9d2131f6e40ba46c9c0e358e4d57178452abd6859bb0" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Makefile b/Makefile index 024306c..d119789 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SHELL := /bin/bash .PHONY: help -ts := $(shell date --utc +%FT%TZ) +ts := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") help: ## This help message @echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)" @@ -53,13 +53,17 @@ plot: bench-compare ## Plot graph from benchmarks @echo "Rendering plots from benchmarks" pipenv run python benchmarks/histogram.py +.PHONY: build-profile +build-profile: ## Builds binary for profiling + cd profiling && pipenv run cargo build --release + # Setup instructions here: # https://gist.github.com/dlaehnemann/df31787c41bd50c0fe223df07cf6eb89 .PHONY: profile profile: OUTPUT_PATH = measurements/flame-$(ts).svg -profile: nightly ## Run perf-based profiling (only works on Linux!) - cd profiling && pipenv run cargo build --release - perf record --call-graph dwarf,16384 -e cpu-clock -F 997 target/release/profiling +profile: FLAGS=booleans --iterations 10000 +profile: nightly build-profile ## Run perf-based profiling (only works on Linux!) + perf record --call-graph dwarf,16384 -e cpu-clock -F 997 target/release/profiling $(FLAGS) time perf script | stackcollapse-perf.pl | c++filt | flamegraph.pl > $(OUTPUT_PATH) @echo "$(OUTPUT_PATH)" diff --git a/profiling/Cargo.toml b/profiling/Cargo.toml index c31d65e..c62ef6d 100644 --- a/profiling/Cargo.toml +++ b/profiling/Cargo.toml @@ -6,6 +6,8 @@ authors = ["Matthias Endler "] [dependencies] # Disabling the default features makes pyo3 choose binary linking hyperjson = { path = "..", default-features = false } +structopt = "0.2.13" +clap = "2.32.0" [dependencies.pyo3] version = "0.5.0" diff --git a/profiling/src/main.rs b/profiling/src/main.rs index 6db8459..9b3e764 100644 --- a/profiling/src/main.rs +++ b/profiling/src/main.rs @@ -14,28 +14,43 @@ //! callgrind_annotate --auto=yes callgrind.out.35583 >out.rs //! qcachegrind callgrind.out.35583 //! ``` +extern crate structopt; +#[macro_use] +extern crate clap; + extern crate hyperjson; extern crate pyo3; -use pyo3::prelude::*; -use std::fs; - +mod profiles; -fn main() { - let bench_file_name = "benchmarks/dict_string_int_plain.txt"; +use structopt::StructOpt; - let dict_string_int = fs::read_to_string(bench_file_name) - .expect(&format!("Could not open bench file '{}'", bench_file_name)); +arg_enum! { + #[derive(Debug)] + enum Profile { + DictStringIntPlain, + Booleans + } +} - let gil = Python::acquire_gil(); - let py = gil.python(); +#[derive(StructOpt, Debug)] +struct Opt { + /// Profile to use + #[structopt(raw(possible_values = "&Profile::variants()", case_insensitive = "true"))] + profile: Profile, - let obj = dict_string_int.to_object(py); + /// Number of profiling iterations + #[structopt(long = "iterations", default_value = "100")] + iterations: u64, +} - for _ in 1..100 { - println!( - "{}", - hyperjson::loads_impl(py, obj.clone_ref(py), None, None, None, None, None, None).is_ok() - ); +fn main() { + let Opt { + profile, + iterations, + } = Opt::from_args(); + match profile { + Profile::DictStringIntPlain => profiles::dict_string_int_plain::exec(iterations), + Profile::Booleans => profiles::booleans::exec(iterations), } } diff --git a/profiling/src/profiles/booleans.rs b/profiling/src/profiles/booleans.rs new file mode 100644 index 0000000..c3906a1 --- /dev/null +++ b/profiling/src/profiles/booleans.rs @@ -0,0 +1,33 @@ +use pyo3::prelude::*; + +pub fn exec(iterations: u64) { + let gil = Python::acquire_gil(); + let py = gil.python(); + + let booleans = format!("[{} \"true\"]", "\"true\",".repeat(255)); + let obj = booleans.to_object(py); + + for _ in 0..iterations { + let deserialized = + hyperjson::loads_impl(py, obj.clone_ref(py), None, None, None, None, None, None) + .unwrap(); + println!( + "{}", + hyperjson::dumps( + py, + deserialized, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + .is_ok() + ); + } +} diff --git a/profiling/src/profiles/dict_string_int_plain.rs b/profiling/src/profiles/dict_string_int_plain.rs new file mode 100644 index 0000000..4722298 --- /dev/null +++ b/profiling/src/profiles/dict_string_int_plain.rs @@ -0,0 +1,22 @@ +use pyo3::prelude::*; +use std::fs; + +pub fn exec(iterations: u64) { + let bench_file_name = "benchmarks/dict_string_int_plain.txt"; + + let dict_string_int = fs::read_to_string(bench_file_name) + .expect(&format!("Could not open bench file '{}'", bench_file_name)); + + let gil = Python::acquire_gil(); + let py = gil.python(); + + let obj = dict_string_int.to_object(py); + + for _ in 0..iterations { + println!( + "{}", + hyperjson::loads_impl(py, obj.clone_ref(py), None, None, None, None, None, None) + .is_ok() + ); + } +} diff --git a/profiling/src/profiles/mod.rs b/profiling/src/profiles/mod.rs new file mode 100644 index 0000000..b36ef70 --- /dev/null +++ b/profiling/src/profiles/mod.rs @@ -0,0 +1,2 @@ +pub mod booleans; +pub mod dict_string_int_plain;