isomorfeus-speednode 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -27
- data/lib/isomorfeus/speednode/attach_pipe.rb +1 -1
- data/lib/isomorfeus/speednode/runner.js +69 -69
- data/lib/isomorfeus/speednode/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6853c585356e8829a315a146dbf12f7625f90eb2d23683147279c5eab581fe4f
|
4
|
+
data.tar.gz: 7fd22dc8309c7d25685cc921853ac52f9ed342dac22ab71883226c2525ca48a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67668d00cf0294ed3df27c4992e95f671799cfea181cb01b33ed4c789870a7e3ab1f953c0d09e0010a8e119e6f5101aa6a31716f54d1498ca1ea5e83bfebc486
|
7
|
+
data.tar.gz: 2ea56bc9974145a6c1bab593c15001e9f7e56edb432ee38a656c2f88087ebb6935ed0f5653f4841bd362d0a70a601e01a55dcedcd9986bf5c5bae6de8257429e
|
data/README.md
CHANGED
@@ -59,7 +59,7 @@ Scripts can be precompiled and stored for repeated execution, which leads to a s
|
|
59
59
|
```ruby
|
60
60
|
context = ExecJS.compile('Test = "test"')
|
61
61
|
context.add_script(key: 'super', source: some_large_javascript) # will compile and store the script
|
62
|
-
context.eval_script(
|
62
|
+
context.eval_script(key: 'super') # will run the precompiled script in the context
|
63
63
|
```
|
64
64
|
For the actual performance benefit see below.
|
65
65
|
|
@@ -96,38 +96,28 @@ Attaching and calling ruby methods to/from permissive contexts is not that fast.
|
|
96
96
|
|
97
97
|
Highly scientific, maybe.
|
98
98
|
|
99
|
-
1000 rounds using node
|
99
|
+
1000 rounds using isomorfeus-speednode 0.6.1 with node 18.15.0 on a older CPU on Linux
|
100
|
+
(ctx = using context, scsc = using precompiled scripts):
|
100
101
|
```
|
101
102
|
standard ExecJS CoffeeScript eval benchmark:
|
102
|
-
|
103
|
-
Isomorfeus Speednode Node.js (V8):
|
104
|
-
Isomorfeus Speednode Node.js (V8) ctx:
|
105
|
-
Isomorfeus Speednode Node.js (V8) scsc:
|
106
|
-
mini_racer (
|
107
|
-
mini_racer (
|
103
|
+
user system total real
|
104
|
+
Isomorfeus Speednode Node.js (V8): 0.107551 0.024227 0.131778 ( 1.034893)
|
105
|
+
Isomorfeus Speednode Node.js (V8) ctx: 0.081142 0.064432 0.145574 ( 0.878249)
|
106
|
+
Isomorfeus Speednode Node.js (V8) scsc: 0.058941 0.040266 0.099207 ( 0.525479)
|
107
|
+
mini_racer (0.6.3, libv8-node 16.10.0): 0.563453 0.416156 0.979609 ( 0.628226)
|
108
|
+
mini_racer (0.6.3, libv8-node 16.10.0) ctx: 0.393274 0.187259 0.580533 ( 0.434056)
|
108
109
|
|
109
110
|
eval overhead benchmark:
|
110
|
-
|
111
|
-
Isomorfeus Speednode Node.js (V8):
|
112
|
-
Isomorfeus Speednode Node.js (V8) ctx:
|
113
|
-
Isomorfeus Speednode Node.js (V8) scsc:
|
114
|
-
mini_racer (
|
115
|
-
mini_racer (
|
116
|
-
|
117
|
-
```
|
118
|
-
minify discourse benchmark from mini_racer:
|
119
|
-
```
|
120
|
-
minify discourse_app_minified.js:
|
121
|
-
user system total real
|
122
|
-
isomorfeus-speednode Windows 0.016000 0.078000 0.094000 ( 11.828518)
|
123
|
-
isomorfeus-speednode Linux 0.043747 0.000000 15.931284 ( 11.860528)
|
124
|
-
mini_racer 0.043471 0.000000 15.974214 ( 11.923735)
|
125
|
-
node 0.043695 0.000000 15.812040 ( 11.781835)
|
111
|
+
user system total real
|
112
|
+
Isomorfeus Speednode Node.js (V8): 0.065491 0.026181 0.091672 ( 0.196204)
|
113
|
+
Isomorfeus Speednode Node.js (V8) ctx: 0.060876 0.029535 0.090411 ( 0.197763)
|
114
|
+
Isomorfeus Speednode Node.js (V8) scsc: 0.036967 0.045451 0.082418 ( 0.133337)
|
115
|
+
mini_racer (0.6.3, libv8-node 16.10.0): 0.070333 0.056378 0.126711 ( 0.100380)
|
116
|
+
mini_racer (0.6.3, libv8-node 16.10.0) ctx: 0.072719 0.049049 0.121768 ( 0.095643)
|
126
117
|
```
|
127
118
|
|
128
119
|
To run benchmarks:
|
129
120
|
- clone repo
|
130
|
-
- `cd ruby`
|
131
121
|
- `bundle install`
|
132
122
|
- `bundle exec rake bench`
|
133
123
|
|
@@ -135,6 +125,5 @@ To run benchmarks:
|
|
135
125
|
|
136
126
|
To run tests:
|
137
127
|
- clone repo
|
138
|
-
- `cd ruby`
|
139
128
|
- `bundle install`
|
140
|
-
- `bundle exec rake
|
129
|
+
- `bundle exec rake`
|
@@ -133,69 +133,69 @@ CircularJSON.stringify = function stringify(value, replacer, space, doNotResolve
|
|
133
133
|
/*** end of circular-json ***/
|
134
134
|
|
135
135
|
function attachFunctionSource(responder_path, context, func) {
|
136
|
-
return func
|
137
|
-
let context =
|
138
|
-
let func =
|
139
|
-
let request = [context, func, method_args]
|
140
|
-
let responder_path = '
|
141
|
-
if (!global.__responder_socket) {
|
142
|
-
return new Promise(function(resolve, reject) {
|
143
|
-
setTimeout(function(){
|
144
|
-
if (os.platform()
|
145
|
-
let socket = net.connect(responder_path)
|
146
|
-
socket.on('connect', function(){
|
147
|
-
global.__responder_socket = true
|
148
|
-
socket.destroy()
|
149
|
-
resolve(
|
150
|
-
})
|
151
|
-
socket.on('error', function (err) {
|
152
|
-
resolve(
|
153
|
-
})
|
154
|
-
} else {
|
155
|
-
if (fs.existsSync(responder_path)) { global.__responder_socket = true; }
|
156
|
-
resolve(
|
157
|
-
}
|
158
|
-
}, 10)
|
159
|
-
})
|
160
|
-
}
|
161
|
-
return new Promise(function(resolve, reject) {
|
162
|
-
let request_json = JSON.stringify(request)
|
163
|
-
let buffer = Buffer.alloc(0)
|
164
|
-
let socket = net.connect(responder_path)
|
165
|
-
socket.setTimeout(2000)
|
166
|
-
socket.on('error', function (err) {
|
167
|
-
if (err.syscall === 'connect') {
|
168
|
-
// ignore, close will handle
|
169
|
-
} else if ((os.platform()
|
170
|
-
// ignore, close will handle
|
171
|
-
} else if ((os.platform()
|
172
|
-
// ignore, close will handle
|
173
|
-
} else { reject(err); }
|
174
|
-
})
|
175
|
-
socket.on('ready', function () {
|
176
|
-
socket.write(request_json +
|
177
|
-
})
|
178
|
-
socket.on('data', function (data) {
|
179
|
-
buffer = Buffer.concat([buffer, data])
|
180
|
-
})
|
181
|
-
socket.on('timeout', function() {
|
182
|
-
socket.destroy()
|
183
|
-
reject()
|
184
|
-
})
|
185
|
-
socket.on('close', function() {
|
186
|
-
if (buffer.length > 0) {
|
187
|
-
let method_result = JSON.parse(buffer.toString('utf8'))
|
188
|
-
if (method_result[0] == 'err') {
|
189
|
-
reject(method_result)
|
190
|
-
} else {
|
191
|
-
resolve(method_result[1])
|
192
|
-
}
|
193
|
-
} else {
|
194
|
-
resolve(null)
|
195
|
-
}
|
196
|
-
})
|
197
|
-
})
|
198
|
-
}
|
136
|
+
return `${func} = async function(...method_args) {
|
137
|
+
let context = '${context}';
|
138
|
+
let func = '${func}';
|
139
|
+
let request = [context, func, method_args];
|
140
|
+
let responder_path = '${responder_path}';
|
141
|
+
if (!global.__responder_socket) {
|
142
|
+
return new Promise(function(resolve, reject) {
|
143
|
+
setTimeout(function(){
|
144
|
+
if (os.platform() == 'win32') {
|
145
|
+
let socket = net.connect(responder_path);
|
146
|
+
socket.on('connect', function(){
|
147
|
+
global.__responder_socket = true;
|
148
|
+
socket.destroy();
|
149
|
+
resolve(${func}(...method_args));
|
150
|
+
})
|
151
|
+
socket.on('error', function (err) {
|
152
|
+
resolve(${func}(...method_args));
|
153
|
+
});
|
154
|
+
} else {
|
155
|
+
if (fs.existsSync(responder_path)) { global.__responder_socket = true; }
|
156
|
+
resolve(${func}(...method_args));
|
157
|
+
}
|
158
|
+
}, 10)
|
159
|
+
});
|
160
|
+
}
|
161
|
+
return new Promise(function(resolve, reject) {
|
162
|
+
let request_json = JSON.stringify(request);
|
163
|
+
let buffer = Buffer.alloc(0);
|
164
|
+
let socket = net.connect(responder_path);
|
165
|
+
socket.setTimeout(2000);
|
166
|
+
socket.on('error', function (err) {
|
167
|
+
if (err.syscall === 'connect') {
|
168
|
+
// ignore, close will handle
|
169
|
+
} else if ((os.platform() == 'win32') && err.message.includes('read EPIPE')) {
|
170
|
+
// ignore, close will handle
|
171
|
+
} else if ((os.platform() == 'win32') && err.message.includes('write EPIPE')) {
|
172
|
+
// ignore, close will handle
|
173
|
+
} else { reject(err); }
|
174
|
+
});
|
175
|
+
socket.on('ready', function () {
|
176
|
+
socket.write(request_json + "\x04");
|
177
|
+
});
|
178
|
+
socket.on('data', function (data) {
|
179
|
+
buffer = Buffer.concat([buffer, data]);
|
180
|
+
});
|
181
|
+
socket.on('timeout', function() {
|
182
|
+
socket.destroy();
|
183
|
+
reject();
|
184
|
+
});
|
185
|
+
socket.on('close', function() {
|
186
|
+
if (buffer.length > 0) {
|
187
|
+
let method_result = JSON.parse(buffer.toString('utf8'));
|
188
|
+
if (method_result[0] == 'err') {
|
189
|
+
reject(method_result);
|
190
|
+
} else {
|
191
|
+
resolve(method_result[1]);
|
192
|
+
}
|
193
|
+
} else {
|
194
|
+
resolve(null);
|
195
|
+
}
|
196
|
+
});
|
197
|
+
});
|
198
|
+
}`;
|
199
199
|
}
|
200
200
|
|
201
201
|
function createCompatibleContext(uuid, options) {
|
@@ -261,7 +261,7 @@ let commands = {
|
|
261
261
|
attach: function(input) {
|
262
262
|
let context = getContext(input.context);
|
263
263
|
let responder_path;
|
264
|
-
if (
|
264
|
+
if (process.platform == 'win32') { responder_path = '\\\\\\\\.\\\\pipe\\\\' + socket_path + '_responder'; }
|
265
265
|
else { responder_path = socket_path + '_responder' }
|
266
266
|
let result = vm.runInContext(attachFunctionSource(responder_path, input.context, input.func), context, { filename: "(execjs)", displayErrors: true });
|
267
267
|
return formatResult(result);
|
@@ -319,15 +319,15 @@ let commands = {
|
|
319
319
|
}
|
320
320
|
},
|
321
321
|
eval: function (input) {
|
322
|
-
if (input.source.match(/^\s*{/)) { input.source =
|
323
|
-
else if (input.source.match(/^\s*function\s*\(/)) { input.source =
|
322
|
+
if (input.source.match(/^\s*{/)) { input.source = `(${input.source})`; }
|
323
|
+
else if (input.source.match(/^\s*function\s*\(/)) { input.source = `(${input.source})`; }
|
324
324
|
let result = vm.runInContext(input.source, getContext(input.context), getContextOptions(input.context));
|
325
325
|
return formatResult(result);
|
326
326
|
},
|
327
327
|
evald: function(input) {
|
328
328
|
if (debug_contexts.includes(input.context)) {
|
329
|
-
if (input.source.match(/^\s*{/)) { input.source =
|
330
|
-
else if (input.source.match(/^\s*function\s*\(/)) { input.source =
|
329
|
+
if (input.source.match(/^\s*{/)) { input.source = `(${input.source})`; }
|
330
|
+
else if (input.source.match(/^\s*function\s*\(/)) { input.source = `(${input.source})`; }
|
331
331
|
let result = eval(input.source);
|
332
332
|
return formatResult(result);
|
333
333
|
} else {
|
@@ -399,5 +399,5 @@ let server = net.createServer(function(s) {
|
|
399
399
|
});
|
400
400
|
});
|
401
401
|
|
402
|
-
if (
|
402
|
+
if (process.platform == 'win32') { server.listen('\\\\.\\pipe\\' + socket_path); }
|
403
403
|
else { server.listen(socket_path); }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isomorfeus-speednode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 3.13.23
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 3.
|
36
|
+
version: 3.16.0
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 3.13.23
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 3.
|
46
|
+
version: 3.16.0
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: win32-pipe
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,14 +78,14 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 5.18.
|
81
|
+
version: 5.18.1
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 5.18.
|
88
|
+
version: 5.18.1
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rake
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '0'
|
159
159
|
requirements: []
|
160
|
-
rubygems_version: 3.4.
|
160
|
+
rubygems_version: 3.4.10
|
161
161
|
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: A fast ExecJS runtime based on nodejs, tuned for Isomorfeus.
|