git ssb

0+

wanderer🌟 / js-dfinity-radix-tree



Commit bef8976f2a564cf623b6149280f7efe17f4a2886

added benchmarkds

wanderer committed on 8/4/2017, 9:43:36 PM
Parent: fb6c040c6945375f945c7613513fc1a550c557fc

Files changed

index.jschanged
package.jsonchanged
tests/index.jschanged
.travis.ymladded
benchmark/ethereum.jsadded
benchmark/multikey.jsadded
benchmark/package.jsonadded
benchmark/radixTree.jsadded
benchmark/results.mdadded
index.jsView
@@ -222,12 +222,12 @@
222222 }
223223 }
224224
225225 /**
226- * creates a merkle root for the current tree
226 + * creates a merkle root for the current tree and stores the data perstantly
227227 * @returns {Promise}
228228 */
229- createMerkleRoot () {
229 + flush () {
230230 return this.graph.flush(this.root)
231231 }
232232
233233 static formatKey (key) {
package.jsonView
@@ -1,18 +1,18 @@
11 {
2- "name": "ipld-radix-tree",
2 + "name": "merkle-radix-tree",
33 "version": "0.0.0",
4- "description": "",
4 + "description": "This implements a binary merkle radix tree",
55 "main": "index.js",
66 "scripts": {
7- "coverage": "node --expose-wasm --harmony ./node_modules/istanbul/lib/cli.js cover ./tests/index.js",
7 + "coverage": "node ./node_modules/istanbul/lib/cli.js cover ./tests/index.js",
88 "coveralls": "npm run coverage && coveralls <coverage/lcov.info",
99 "lint": "standard",
10- "test": "node --expose-wasm --harmony ./tests/index.js"
10 + "test": "node ./tests/index.js"
1111 },
1212 "author": "mjbecze <mjbecze@gmail.com>",
1313 "license": "MPL-2.0",
14- "keywords": [],
14 + "keywords": ["merkle", "tree", "ipfs"],
1515 "devDependencies": {
1616 "coveralls": "^2.13.1",
1717 "ipfs": "^0.25.0",
1818 "istanbul": "^1.1.0-alpha.1",
tests/index.jsView
@@ -32,9 +32,9 @@
3232 await tree.set('test', 'cat111')
3333 val = await tree.get('test')
3434 t.equals(val, 'cat111')
3535
36- const stateRoot = await tree.createMerkleRoot()
36 + const stateRoot = await tree.flush()
3737
3838 // try reteriving node from ipfs
3939 tree = new RadixTree({
4040 dag: node.dag,
@@ -67,8 +67,17 @@
6767 let key2 = new RadixTree.ArrayConstructor([1, 0])
6868 await tree.set(key2, 'cat')
6969 let key3 = new RadixTree.ArrayConstructor([0, 0])
7070 await tree.set(key3, 'cat3')
71 +
72 + let val = await tree.get(key0)
73 + t.equals(val, 'cat')
74 + val = await tree.get(key1)
75 + t.equals(val, 'cat2')
76 + val = await tree.get(key2)
77 + t.equals(val, 'cat')
78 + val = await tree.get(key3)
79 + t.equals(val, 'cat3')
7180 // console.log(JSON.stringify(tree.root, null, 2))
7281
7382 t.end()
7483 })
.travis.ymlView
@@ -1,0 +1,24 @@
1 +language: node_js
2 +node_js:
3 + - "8"
4 +env:
5 + global:
6 + - CXX=g++-4.8
7 + matrix:
8 + - TEST_SUITE=test
9 +addons:
10 + apt:
11 + sources:
12 + - ubuntu-toolchain-r-test
13 + packages:
14 + - g++-4.8
15 +matrix:
16 + fast_finish: true
17 + include:
18 + - os: linux
19 + node_js: "8"
20 + env: TEST_SUITE=coveralls
21 + - os: linux
22 + node_js: "8"
23 + env: TEST_SUITE=lint
24 +script: npm run $TEST_SUITE
benchmark/ethereum.jsView
@@ -1,0 +1,36 @@
1 +var Trie = require('merkle-patricia-tree')
2 +const crypto = require('crypto')
3 +const rlp = require('rlp')
4 +
5 +const trie = new Trie()
6 +
7 +const entries = 100000
8 +console.log('entries', entries)
9 +
10 +async function run () {
11 + for (let i = 0; i < entries; i++) {
12 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
13 + await new Promise((resolve, reject) => {
14 + trie.put(key, i, resolve)
15 + })
16 + }
17 +
18 + let proofSize = 0
19 + for (let i = 0; i < entries; i++) {
20 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
21 + const promise = new Promise((resolve, reject) => {
22 + trie.findPath(key, (err, node, remainder, stack) => {
23 + let proof = stack.map(el => {
24 + return el.raw
25 + })
26 + let encoded = rlp.encode(proof)
27 + proofSize += encoded.length
28 + resolve()
29 + })
30 + })
31 + await promise
32 + }
33 + console.log('rlp size', proofSize / entries)
34 +}
35 +
36 +run()
benchmark/multikey.jsView
@@ -1,0 +1,75 @@
1 +const IPFS = require('ipfs')
2 +const crypto = require('crypto')
3 +const RadixTree = require('../')
4 +const cbor = require('borc')
5 +const zlib = require('zlib')
6 +
7 +// start ipfs
8 +const node = new IPFS({
9 + start: false,
10 + repo: './ipfs-repo'
11 +})
12 +
13 +node.on('ready', async () => {
14 + const tree = new RadixTree({
15 + dag: node.dag,
16 + // root: { '/': 'zdpuArkpWFfw49S1tNLY26YNkHCoKt2CG7rJ6iCaqkcwsGqH7' }
17 + })
18 +
19 + const entries = 10000 //5117051
20 + console.log('entries', entries)
21 + for (let i = 0; i < entries; i++) {
22 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
23 + await tree.set(key, i)
24 + }
25 + console.log('flushing')
26 + const sr = await tree.flush()
27 + console.log('done', sr)
28 +
29 + let proofSize = 0
30 + let compressedSize = 0
31 +
32 + const gzip = zlib.createGzip()
33 + gzip.on('data', (data) => {
34 + compressedSize += data.length
35 + })
36 +
37 + const numOfKeys = 3
38 + for (let i = 0; i < numOfKeys; i++) {
39 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
40 + await tree.get(key)
41 + }
42 +
43 + const encoded = cbor.encode(tree.root)
44 + proofSize += encoded.length
45 +
46 + const promise = new Promise((resolve, reject) => {
47 + gzip.on('end', () => {
48 + resolve()
49 + })
50 + })
51 + gzip.end(encoded)
52 + await promise
53 + console.log('cbor size', proofSize)
54 + console.log('compressed size', compressedSize)
55 +})
56 +
57 +// if (i % 10000 === 0) {
58 +// console.log(i)
59 +// console.log(JSON.stringify(tree.root, null, 2))
60 +// try {
61 +// let start = new Date()
62 +// let hrstart = process.hrtime()
63 +// await tree.flush()
64 +// const end = new Date() - start
65 +// const hrend = process.hrtime(hrstart)
66 +
67 +// console.info('Execution time: %dms', end)
68 +// console.info('Execution time (hr): %ds %dms', hrend[0], hrend[1] / 1000000)
69 +// console.log(tree.root)
70 +// start = new Date()
71 +// hrstart = process.hrtime()
72 +// } catch (e) {
73 +// console.log(e)
74 +// }
75 +// }
benchmark/package.jsonView
@@ -1,0 +1,15 @@
1 +{
2 + "name": "benchmark",
3 + "version": "1.0.0",
4 + "description": "",
5 + "main": "index.js",
6 + "scripts": {
7 + "test": "echo \"Error: no test specified\" && exit 1"
8 + },
9 + "author": "",
10 + "license": "ISC",
11 + "dependencies": {
12 + "borc": "^2.0.2",
13 + "merkle-patricia-tree": "^2.2.0"
14 + }
15 +}
benchmark/radixTree.jsView
@@ -1,0 +1,77 @@
1 +const IPFS = require('ipfs')
2 +const crypto = require('crypto')
3 +const RadixTree = require('../')
4 +const cbor = require('borc')
5 +const zlib = require('zlib')
6 +
7 +// start ipfs
8 +const node = new IPFS({
9 + start: false,
10 + repo: './ipfs-repo'
11 +})
12 +
13 +node.on('ready', async () => {
14 + const tree = new RadixTree({
15 + dag: node.dag,
16 + // root: { '/': 'zdpuArkpWFfw49S1tNLY26YNkHCoKt2CG7rJ6iCaqkcwsGqH7' }
17 + })
18 +
19 + const entries = 100000 //5117051
20 + console.log('entries', entries)
21 + for (let i = 0; i < entries; i++) {
22 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
23 + await tree.set(key, i)
24 + }
25 + console.log('flushing')
26 + const sr = await tree.flush()
27 + console.log('done', sr)
28 +
29 + let proofSize = 0
30 + let compressedSize = 0
31 +
32 + for (let i = 0; i < entries; i++) {
33 + const tree = new RadixTree({
34 + dag: node.dag,
35 + root: {'/': sr['/']}
36 + })
37 + const key = crypto.createHash('sha256').update(i.toString()).digest().slice(0, 20)
38 + await tree.get(key)
39 + // console.log(JSON.stringify(tree.root, null, 2))
40 + const encoded = cbor.encode(tree.root)
41 + proofSize += encoded.length
42 +
43 + const gzip = zlib.createGzip()
44 + gzip.on('data', (data) => {
45 + compressedSize += data.length
46 + })
47 + const promise = new Promise((resolve, reject) => {
48 + gzip.on('end', () => {
49 + resolve()
50 + })
51 + })
52 + gzip.end(encoded)
53 + await promise
54 + }
55 + console.log('cbor size', proofSize / entries)
56 + console.log('compressed size', compressedSize / entries)
57 +})
58 +
59 +// if (i % 10000 === 0) {
60 +// console.log(i)
61 +// console.log(JSON.stringify(tree.root, null, 2))
62 +// try {
63 +// let start = new Date()
64 +// let hrstart = process.hrtime()
65 +// await tree.flush()
66 +// const end = new Date() - start
67 +// const hrend = process.hrtime(hrstart)
68 +
69 +// console.info('Execution time: %dms', end)
70 +// console.info('Execution time (hr): %ds %dms', hrend[0], hrend[1] / 1000000)
71 +// console.log(tree.root)
72 +// start = new Date()
73 +// hrstart = process.hrtime()
74 +// } catch (e) {
75 +// console.log(e)
76 +// }
77 +// }
benchmark/results.mdView
@@ -1,0 +1,163 @@
1 +This compares the binary radix tree's proof to Ethereum tree. The proofs where
2 +encoded in cbor and compressed with gzip. Etherum's proof where encoded using
3 +rlp. The compressed results for Ethereum where not recoded since they where
4 +larger then the uncompressed proofs
5 +
6 +## 10000 keys
7 +### Binary Radix Tree
8 +```
9 +cbor 660 bytes
10 +compressed size 572
11 +```
12 +
13 +### Ethereum
14 +```
15 +rlp 1649 bytes
16 +```
17 +
18 +Diff 65%
19 +
20 +## 20000 keys
21 +### Binary Radix Tree
22 +```
23 +cbor 705 bytes
24 +compressed size 607
25 +```
26 +
27 +### Ethereum
28 +```
29 +rlp 1772 bytes
30 +```
31 +
32 +Diff 66%
33 +
34 +## 30000 keys
35 +### Binary Radix Tree
36 +```
37 +cbor 731 bytes
38 +compressed 628 size
39 +```
40 +
41 +### Ethereum
42 +```
43 +rlp 1829 bytes
44 +```
45 +
46 +Diff 66%
47 +
48 +## 40000 keys
49 +### Binary Radix Tree
50 +```
51 +cbor 749 bytes
52 +compressed 643 size
53 +```
54 +
55 +### Ethereum
56 +```
57 +rlp 1876 bytes
58 +```
59 +
60 +Diff 66%
61 +
62 +## 50000 keys
63 +### Binary Radix Tree
64 +```
65 +cbor 764 bytes
66 +compressed 654 size
67 +```
68 +
69 +### Ethereum
70 +```
71 +rlp 1917 bytes
72 +```
73 +
74 +Diff 66%
75 +
76 +## 60000 keys
77 +### Binary Radix Tree
78 +```
79 +cbor 776 bytes
80 +compressed 663 size
81 +```
82 +
83 +### Ethereum
84 +```
85 +rlp 1956 bytes
86 +```
87 +
88 +## 70000 keys
89 +### Binary Radix Tree
90 +```
91 +cbor 786 bytes
92 +compressed 671 size
93 +```
94 +
95 +### Ethereum
96 +```
97 +rlp 1990 bytes
98 +```
99 +
100 +Diff 66%
101 +
102 +## 80000 keys
103 +### Binary Radix Tree
104 +```
105 +cbor 795 bytes
106 +compressed 679 size
107 +```
108 +
109 +### Ethereum
110 +```
111 +rlp 2021 bytes
112 +```
113 +
114 +Diff 66%
115 +
116 +## 90000 keys
117 +### Binary Radix Tree
118 +```
119 +cbor 803 bytes
120 +compressed 685 size
121 +```
122 +
123 +### Ethereum
124 +```
125 +rlp 2050 bytes
126 +```
127 +
128 +Diff 67%
129 +
130 +## 100000 keys
131 +### Binary Radix Tree
132 +```
133 +cbor 810 bytes
134 +compressed 691 size
135 +```
136 +
137 +### Ethereum
138 +```
139 +rlp 2075 bytes
140 +```
141 +
142 +Diff 67%
143 +
144 +# multikey
145 +The following show that multikey are more compact the single key proofs . Each
146 +tree was populated with 10000 keys
147 +
148 +## Two Keys Proofs
149 +```
150 +cbor 1088
151 +compressed 916
152 +```
153 +
154 +## Three Keys Proofs
155 +```
156 +cbor 1675
157 +compressed 1381
158 +```
159 +## Four Keys Proofs
160 +```
161 +cbor 2221
162 +compressed 1801
163 +```

Built with git-ssb-web