NodeJs와 간단한 성능 테스트

This commit is contained in:
freestrings 2019-03-07 18:44:06 +09:00
parent cd01540d75
commit f7b564dcd3
16 changed files with 441 additions and 20 deletions

View File

@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/freestrings/jsonpath.svg?branch=master)](https://travis-ci.org/freestrings/jsonpath)
`Rust` 버전 [JsonPath](https://goessner.net/articles/JsonPath/) 구현이다. Rust 구현과 동일한 기능을 `Webassembly` 로 제공하는 것 또한 목적이다.
`Rust` 버전 [JsonPath](https://goessner.net/articles/JsonPath/) 구현이다. Rust 구현과 동일한 기능을 `Webassembly` 로 제공하는 것도 목표.
The `Rust` version is a [JsonPath](https://goessner.net/articles/JsonPath/) implementation. It is also aimed to provide the same functionality as `Webassembly` in Rust implementation.

View File

@ -1,12 +1,10 @@
#![feature(test)]
extern crate jsonpath;
extern crate jsonpath_lib as jsonpath;
extern crate serde_json;
extern crate test;
use std::io::Read;
use serde_json::Value;
use self::test::Bencher;
fn read_json(path: &str) -> String {
@ -17,22 +15,13 @@ fn read_json(path: &str) -> String {
}
#[bench]
fn bench_a(b: &mut Bencher) {
let string = read_json("./benches/data_array.json");
let v: Value = serde_json::from_str(string.as_str()).unwrap();
fn bench_reader(b: &mut Bencher) {
let string = read_json("./benches/example.json");
let json: Value = serde_json::from_str(string.as_str()).unwrap();
let mut reader = jsonpath::reader(json);
b.iter(move || {
for _ in 1..1000 {
let _ = v.clone();
}
});
}
#[bench]
fn bench_b(b: &mut Bencher) {
let string = read_json("./benches/data_array.json");
b.iter(move || {
for _ in 1..1000 {
let _: Value = serde_json::from_str(string.as_str()).unwrap();
for _ in 1..10000 {
let _ = reader("$.store").unwrap();
}
});
}

4
benches/bench_bin/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
bin/

View File

@ -0,0 +1,7 @@
[package]
name = "bench_bin"
version = "0.1.0"
[dependencies]
jsonpath_lib = {path = "../../"}
serde_json = { version = "1.0", features = ["preserve_order"] }

8
benches/bench_bin/bench.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
if [ -d "target/release" ]; then
./target/release/bench_bin
else
echo "빌드먼저"
fi

View File

@ -0,0 +1,21 @@
extern crate jsonpath_lib as jsonpath;
extern crate serde_json;
use serde_json::Value;
use std::io::Read;
fn read_json(path: &str) -> String {
let mut f = std::fs::File::open(path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
contents
}
fn main() {
let string = read_json("../example.json");
let json: Value = serde_json::from_str(string.as_str()).unwrap();
let mut reader = jsonpath::reader(json);
for _ in 1..100000 {
let _ = reader(r#"$..book[?(@.price<30 && @.category=="fiction")]"#).unwrap();
}
}

13
benches/bench_node_vs_rust.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
set -e
DIR="$(pwd)"
cd "${DIR}"/bench_bin && cargo build --release
printf "\n\n$..book[?(@.price<30 && @.category=="fiction")] (loop 100,000)"
printf "\n\n"
echo "Rust: " && time ./bench.sh
printf "\n"
cd "${DIR}"/javascript && echo "NodeJs: " && time ./bench.sh

2
benches/javascript/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
dist

108
benches/javascript/bench.js Normal file
View File

@ -0,0 +1,108 @@
let json = {
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
};
const jp = require('jsonpath');
const jpw = require('jsonpath-wasm');
const Benchmark = require('benchmark');
function compareJsonpath(path) {
let r1 = jp.query(json, path);
let r2 = jpw.read(json, path);
let template = jpw.compile(path);
var suite = new Benchmark.Suite;
suite.add('jp', function() {
jp.query(json, path);
})
.add('jpw', function() {
template(json);
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
console.log('Slowest is ' + this.filter('slowest').map('name'));
})
.run({ 'async': true });
}
function compareEmptyFunction() {
var suite = new Benchmark.Suite;
suite.add('js', function() {
})
.add('rust', function() {
jpw.testa();
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
console.log('Slowest is ' + this.filter('slowest').map('name'));
})
.run({});
}
function jsonpathOnly() {
for(var i = 0; i < 100000 ; i++) {
let _ = jp.query(json, '$..book[?(@.price<30 && @.category==\"fiction\")]');
}
}
if(process.argv.length < 3) {
let functions = ['', 'compareJsonpath', 'compareEmptyFunction', 'jsonpathOnly'];
console.log("node bench.js", functions.join("\n\t|"));
return;
}
let functionName = process.argv[2];
switch (functionName) {
case 'compareJsonpath':
compareJsonpath('$..book[?(@.price<30 && @.category==\"fiction\")]');
break;
case 'compareEmptyFunction':
compareEmptyFunction();
break;
default:
jsonpathOnly();
}

2
benches/javascript/bench.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
node bench.js jsonpathOnly

244
benches/javascript/package-lock.json generated Normal file
View File

@ -0,0 +1,244 @@
{
"name": "jsonpath-benches",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"JSONSelect": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
"integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
},
"benchmark": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
"integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=",
"requires": {
"lodash": "^4.17.4",
"platform": "^1.3.3"
}
},
"cjson": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cjson/-/cjson-0.2.1.tgz",
"integrity": "sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU="
},
"colors": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
"integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"ebnf-parser": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz",
"integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE="
},
"escodegen": {
"version": "0.0.21",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.21.tgz",
"integrity": "sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=",
"requires": {
"esprima": "~1.0.2",
"estraverse": "~0.0.4",
"source-map": ">= 0.1.2"
},
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"esprima": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
"integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs="
},
"estraverse": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-0.0.4.tgz",
"integrity": "sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI="
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"jison": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
"integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=",
"requires": {
"JSONSelect": "0.4.0",
"cjson": "~0.2.1",
"ebnf-parser": "~0.1.9",
"escodegen": "0.0.21",
"esprima": "1.0.x",
"jison-lex": "0.2.x",
"lex-parser": "~0.1.3",
"nomnom": "1.5.2"
},
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"jison-lex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.2.1.tgz",
"integrity": "sha1-rEuBXozOUTLrErXfz+jXB7iETf4=",
"requires": {
"lex-parser": "0.1.x",
"nomnom": "1.5.2"
}
},
"jsonpath": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.1.tgz",
"integrity": "sha512-HY5kSg82LHIs0r0h9gYBwpNc1w1qGY0qJ7al01W1bJltsN2lp+mjjA/a79gXWuvD6Xf8oPkD2d5uKMZQXTGzqA==",
"requires": {
"esprima": "1.2.2",
"jison": "0.4.13",
"static-eval": "2.0.2",
"underscore": "1.7.0"
}
},
"jsonpath-wasm": {
"version": "0.1.1"
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lex-parser": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz",
"integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA="
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"nomnom": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
"integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
"requires": {
"colors": "0.5.x",
"underscore": "1.1.x"
},
"dependencies": {
"underscore": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz",
"integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA="
}
}
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.4",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"wordwrap": "~1.0.0"
}
},
"platform": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz",
"integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q=="
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"optional": true
},
"static-eval": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
"integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==",
"requires": {
"escodegen": "^1.8.1"
},
"dependencies": {
"escodegen": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz",
"integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
"requires": {
"esprima": "^3.1.3",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
}
},
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
}
}
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"underscore": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
}
}
}

View File

@ -0,0 +1,13 @@
{
"name": "jsonpath-benches",
"version": "1.0.0",
"main": "bench.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"jsonpath": "*",
"jsonpath-wasm": "*",
"benchmark": "*"
}
}

5
benches/javascript/setup.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
set -e
cd ../../wasm && ./build.sh nodejs
cd ../benches/javascript && npm link jsonpath-wasm

View File

@ -14,7 +14,7 @@ license = "MIT"
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
default = ["console_error_panic_hook", "wee_alloc"]
[dependencies]
cfg-if = "0.1.2"

1
wasm/node_modules/jsonpath-wasm generated vendored Symbolic link
View File

@ -0,0 +1 @@
../../../../../.nvm/versions/node/v11.10.1/lib/node_modules/jsonpath-wasm

View File

@ -92,4 +92,8 @@ pub fn read(js_value: JsValue, path: &str) -> JsValue {
Ok(node) => into_js_value(&js_value, node),
Err(e) => return JsValue::from_str(e.as_str())
}
}
#[wasm_bindgen]
pub fn testa() {
}