This PR is not ready: I know univalue is handled in a separate repository, so I guess I have to split the PR up? Where should the univalue changes go to, into https://github.com/bitcoin-core/univalue or into https://github.com/jgarzik/univalue?
Anyways, here is some motivational data for the changes:
For my BitcoinUtxoVisualizer the limiting factor seems to be mostly bitcoind’s JSON generation speed. Here are some optimizations that speed this up quite a bit for me. Here are some numbers:
./bench_bitcoin -filter=BlockToJsonVerbose
| ns/op | err% | bra/op | miss% | benchmarked commit | 
|---|---|---|---|---|
| 66,877,763.00 | 0.1% | 101,638,376.00 | 0.4% | 349f17e | 
| 57,915,056.00 | 1.2% | 85,882,830.00 | 0.5% | 26fd10a | 
| 36,585,334.00 | 1.6% | 50,966,277.00 | 0.4% | 93f8240 | 
| 28,508,105.00 | 0.2% | 40,138,962.00 | 0.4% | 9b59b15 | 
So the benchmark improves from 66.9ms to 28.5ms for me. I ran an a benchmark with bitcoind as well, with that protocol:
- start bitcoind, with this bitcoin.conf:0server=1 1rest=1 2rpcport=8332 3rpcthreads=32 4rpcworkqueue=64 5txindex=1 6dbcache=2000
- Wait until fully synced, and log message shows loadblk thread exit, so that bitcoind is idle.
- Run apache benchmark: 2000 requests, 12 parallel threads, fetching block nr. 600000:
0ab -n 2000 -c 12 "http://127.0.0.1:8332/rest/block/00000000000000000007316856900e76b4f7a9139cfbfba89842c8d196cd5f91.json"
Results for master, 349f17e:
 0    Concurrency Level:      12
 1    Time taken for tests:   26.535 seconds
 2    Complete requests:      2000
 3    Failed requests:        0
 4    Total transferred:      11192226000 bytes
 5    HTML transferred:       11192124000 bytes
 6    Requests per second:    75.37 [#/sec] (mean)
 7    Time per request:       159.208 [ms] (mean)
 8    Time per request:       13.267 [ms] (mean, across all concurrent requests)
 9    Transfer rate:          411911.64 [Kbytes/sec] received
10
11    Connection Times (ms)
12                min  mean[+/-sd] median   max
13    Connect:        0    0   0.0      0       0
14    Processing:    93  158  15.0    156     283
15    Waiting:       91  154  14.8    152     280
16    Total:         93  158  15.0    156     283
17
18    Percentage of the requests served within a certain time (ms)
19    50%    156
20    66%    161
21    75%    164
22    80%    167
23    90%    174
24    95%    184
25    98%    200
26    99%    216
27    100%    283 (longest request)
Results for this PR, 9b59b15:
 0    Concurrency Level:      12
 1    Time taken for tests:   16.801 seconds
 2    Complete requests:      2000
 3    Failed requests:        0
 4    Total transferred:      11192226000 bytes
 5    HTML transferred:       11192124000 bytes
 6    Requests per second:    119.04 [#/sec] (mean)
 7    Time per request:       100.805 [ms] (mean)
 8    Time per request:       8.400 [ms] (mean, across all concurrent requests)
 9    Transfer rate:          650556.74 [Kbytes/sec] received
10
11    Connection Times (ms)
12                min  mean[+/-sd] median   max
13    Connect:        0    0   0.0      0       0
14    Processing:    38  100  19.1     98     211
15    Waiting:       36   98  19.0     96     208
16    Total:         38  100  19.1     98     211
17
18    Percentage of the requests served within a certain time (ms)
19    50%     98
20    66%    105
21    75%    110
22    80%    113
23    90%    123
24    95%    138
25    98%    155
26    99%    163
27    100%    211 (longest request)