3
3
"use strict" ;
4
4
require ( "ts-node/register" ) ;
5
5
const Benchmark = require ( "benchmark" ) ;
6
- const fs = require ( "fs" ) ;
7
- const msgpack = require ( "../src" ) ;
6
+
7
+ const msgpackEncode = require ( ".." ) . encode ;
8
+ const msgpackDecode = require ( ".." ) . decode ;
9
+ const ExtensionCodec = require ( ".." ) . ExtensionCodec ;
10
+
11
+ const float32ArrayExtensionCodec = new ExtensionCodec ( ) ;
12
+ float32ArrayExtensionCodec . register ( {
13
+ type : 0x01 ,
14
+ encode : ( object ) => {
15
+ if ( object instanceof Float32Array ) {
16
+ return new Uint8Array ( object . buffer , object . byteOffset , object . byteLength ) ;
17
+ }
18
+ return null ;
19
+ } ,
20
+ decode : ( data ) => {
21
+ const copy = new Uint8Array ( data . byteLength ) ;
22
+ copy . set ( data ) ;
23
+ return new Float32Array ( copy . buffer ) ;
24
+ } ,
25
+ } ) ;
26
+
27
+ const float32ArrayZeroCopyExtensionCodec = new ExtensionCodec ( ) ;
28
+ float32ArrayZeroCopyExtensionCodec . register ( {
29
+ type : 0x01 ,
30
+ encode : ( object ) => {
31
+ if ( object instanceof Float32Array ) {
32
+ return ( pos ) => {
33
+ const bpe = Float32Array . BYTES_PER_ELEMENT ;
34
+ const padding = 1 + ( ( bpe - ( ( pos + 1 ) % bpe ) ) % bpe ) ;
35
+ const data = new Uint8Array ( object . buffer ) ;
36
+ const result = new Uint8Array ( padding + data . length ) ;
37
+ result [ 0 ] = padding ;
38
+ result . set ( data , padding ) ;
39
+ return result ;
40
+ } ;
41
+ }
42
+ return null ;
43
+ } ,
44
+ decode : ( data ) => {
45
+ const padding = data [ 0 ] ;
46
+ const bpe = Float32Array . BYTES_PER_ELEMENT ;
47
+ const offset = data . byteOffset + padding ;
48
+ const length = data . byteLength - padding ;
49
+ return new Float32Array ( data . buffer , offset , length / bpe ) ;
50
+ } ,
51
+ } ) ;
8
52
9
53
const implementations = {
10
54
"@msgpack/msgpack" : {
11
- encode : require ( ".." ) . encode ,
12
- decode : require ( ".." ) . decode ,
55
+ encode : msgpackEncode ,
56
+ decode : msgpackDecode ,
57
+ } ,
58
+ "@msgpack/msgpack (Float32Array extension)" : {
59
+ encode : ( data ) => msgpackEncode ( data , { extensionCodec : float32ArrayExtensionCodec } ) ,
60
+ decode : ( data ) => msgpackDecode ( data , { extensionCodec : float32ArrayExtensionCodec } ) ,
61
+ } ,
62
+ "@msgpack/msgpack (Float32Array with zero-copy extension)" : {
63
+ encode : ( data ) => msgpackEncode ( data , { extensionCodec : float32ArrayZeroCopyExtensionCodec } ) ,
64
+ decode : ( data ) => msgpackDecode ( data , { extensionCodec : float32ArrayZeroCopyExtensionCodec } ) ,
13
65
} ,
14
66
"msgpack-lite" : {
15
67
encode : require ( "msgpack-lite" ) . encode ,
@@ -21,28 +73,52 @@ const implementations = {
21
73
} ,
22
74
} ;
23
75
24
- // exactly the same as:
25
- // https://raw.githubusercontent.com/endel/msgpack-benchmark/master/sample-large.json
26
- const sampleFiles = [ "./sample-large.json" ] ;
76
+ const samples = [
77
+ {
78
+ // exactly the same as:
79
+ // https://raw.githubusercontent.com/endel/msgpack-benchmark/master/sample-large.json
80
+ name : "./sample-large.json" ,
81
+ data : require ( "./sample-large.json" ) ,
82
+ } ,
83
+ {
84
+ name : "Large array of numbers" ,
85
+ data : [
86
+ {
87
+ position : new Array ( 1e3 ) . fill ( 1.14 ) ,
88
+ } ,
89
+ ] ,
90
+ } ,
91
+ {
92
+ name : "Large Float32Array" ,
93
+ data : [
94
+ {
95
+ position : new Float32Array ( 1e3 ) . fill ( 1.14 ) ,
96
+ } ,
97
+ ] ,
98
+ } ,
99
+ ] ;
27
100
28
101
function validate ( name , data , encoded ) {
29
- if ( JSON . stringify ( data ) !== JSON . stringify ( implementations [ name ] . decode ( encoded ) ) ) {
30
- throw new Error ( "Bad implementation: " + name ) ;
31
- }
102
+ return JSON . stringify ( data ) === JSON . stringify ( implementations [ name ] . decode ( encoded ) ) ;
32
103
}
33
104
34
- for ( const sampleFile of sampleFiles ) {
35
- const data = require ( sampleFile ) ;
105
+ for ( const sample of samples ) {
106
+ const { name : sampleName , data } = sample ;
36
107
const encodeSuite = new Benchmark . Suite ( ) ;
37
108
const decodeSuite = new Benchmark . Suite ( ) ;
38
109
39
110
console . log ( "" ) ;
40
- console . log ( "**" + sampleFile + ":** (" + JSON . stringify ( data ) . length + " bytes in JSON)" ) ;
111
+ console . log ( "**" + sampleName + ":** (" + JSON . stringify ( data ) . length + " bytes in JSON)" ) ;
41
112
console . log ( "" ) ;
42
113
43
114
for ( const name of Object . keys ( implementations ) ) {
44
115
implementations [ name ] . toDecode = implementations [ name ] . encode ( data ) ;
45
- validate ( name , data , implementations [ name ] . toDecode ) ;
116
+ if ( ! validate ( name , data , implementations [ name ] . toDecode ) ) {
117
+ console . log ( "```" ) ;
118
+ console . log ( "Not supported by " + name ) ;
119
+ console . log ( "```" ) ;
120
+ continue ;
121
+ }
46
122
encodeSuite . add ( "(encode) " + name , ( ) => {
47
123
implementations [ name ] . encode ( data ) ;
48
124
} ) ;
@@ -60,7 +136,7 @@ for (const sampleFile of sampleFiles) {
60
136
61
137
console . log ( "" ) ;
62
138
63
- decodeSuite . on ( "cycle" , function ( event ) {
139
+ decodeSuite . on ( "cycle" , ( event ) => {
64
140
console . log ( String ( event . target ) ) ;
65
141
} ) ;
66
142
0 commit comments