mini_racer 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7469d9f13294a9088aaf40f823c0d027a9f50bf6
4
- data.tar.gz: b34b103238ba3f509a3b46382b62ba6f9f2b8500
3
+ metadata.gz: bcbf79004383ed09c2b2ceb6821a13a01ef11c36
4
+ data.tar.gz: d18d5d701d8067a011f2e778c257a076036cb029
5
5
  SHA512:
6
- metadata.gz: 134198f0aae35ca62a8c2f7e2d083c9ca7c8cc0a07568039b60953dc0c65957118023a56e4d7c97acde43f6951cd83f79aaa1684fc4178ae9314e4d0811e2614
7
- data.tar.gz: cb287c13bdd6ca8d0f8ecc738d8cb97d75b609973e19e5529dd39c5afa2dc425f1416532694e5aeab66df6b5667f99f3df1f723ed004d37c1cd150d344d45ccb
6
+ metadata.gz: fa133304bbbbac7c0a7cd205d19928cc0bfd074a340c0ef18ceef92bff9bc4e3ff4924085c418ee32e14663c84c856837f7f745b09db65d5ecd89241b5081689
7
+ data.tar.gz: 9bbfa1a279aef49bcfe500583b73796c4766bc5bbbd278f1d3c76bdf8c9ce2df67d292f2c1e25d94e739f532f252356497b7e4d43dc94fab9c0e8d0819b2cd09
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 09-03-2017
2
+
3
+ - 0.1.9
4
+
5
+ - Perf: speed up ruby/node boundary performance when moving large objects
6
+
1
7
  06-02-2017
2
8
 
3
9
  - 0.1.8
data/README.md CHANGED
@@ -232,22 +232,31 @@ The `bench` folder contains benchmark.
232
232
 
233
233
  ### Benchmark minification of Discourse application.js (both minified and unminified)
234
234
 
235
- - MiniRacer version 0.1
235
+ MiniRacer outperforms node when minifying assets via execjs.
236
+
237
+ - MiniRacer version 0.1.9
238
+ - node version 6.10
236
239
  - therubyracer version 0.12.2
237
240
 
238
- ```
239
- $ ruby bench_uglify.rb
240
- Benching with MiniRacer
241
- MiniRacer minify discourse_app.js 13813.36ms
242
- MiniRacer minify discourse_app_minified.js 18271.19ms
243
- MiniRacer minify discourse_app.js twice (2 threads) 13587.21ms
244
241
  ```
245
242
 
246
- ```
243
+ $ bundle exec ruby bench.rb mini_racer
244
+ Benching with mini_racer
245
+ mini_racer minify discourse_app.js 9292.72063ms
246
+ mini_racer minify discourse_app_minified.js 11799.850171ms
247
+ mini_racer minify discourse_app.js twice (2 threads) 10269.570797ms
248
+
249
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb node
250
+ Benching with node
251
+ node minify discourse_app.js 13302.715484ms
252
+ node minify discourse_app_minified.js 18100.761243ms
253
+ node minify discourse_app.js twice (2 threads) 14383.600207000001ms
254
+
255
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb therubyracer
247
256
  Benching with therubyracer
248
- MiniRacer minify discourse_app.js 151467.164ms
249
- MiniRacer minify discourse_app_minified.js 158172.097ms
250
- MiniRacer minify discourse_app.js twice (2 threads) - DOES NOT FINISH
257
+ therubyracer minify discourse_app.js 171683.01867700001ms
258
+ therubyracer minify discourse_app_minified.js 143138.88492ms
259
+ therubyracer minify discourse_app.js twice (2 threads) NEVER FINISH
251
260
 
252
261
  Killed: 9
253
262
  ```
@@ -256,6 +265,8 @@ The huge performance disparity (MiniRacer is 10x faster) is due to MiniRacer run
256
265
 
257
266
  Note how the global interpreter lock release leads to 2 threads doing the same work taking the same wall time as 1 thread.
258
267
 
268
+ As a rule MiniRacer strives to always support and depend on the latest stable version of libv8.
269
+
259
270
  ## Installation
260
271
 
261
272
  Add this line to your application's Gemfile:
@@ -50,6 +50,7 @@ typedef struct {
50
50
  bool parsed;
51
51
  bool executed;
52
52
  bool terminated;
53
+ bool json;
53
54
  Persistent<Value>* value;
54
55
  Persistent<Value>* message;
55
56
  Persistent<Value>* backtrace;
@@ -68,6 +69,7 @@ static VALUE rb_eScriptRuntimeError;
68
69
  static VALUE rb_cJavaScriptFunction;
69
70
  static VALUE rb_eSnapshotError;
70
71
  static VALUE rb_ePlatformAlreadyInitializedError;
72
+ static VALUE rb_mJSON;
71
73
 
72
74
  static VALUE rb_cFailedV8Conversion;
73
75
  static VALUE rb_cDateTime = Qnil;
@@ -118,11 +120,10 @@ nogvl_context_eval(void* arg) {
118
120
  EvalParams* eval_params = (EvalParams*)arg;
119
121
  EvalResult* result = eval_params->result;
120
122
  Isolate* isolate = eval_params->context_info->isolate_info->isolate;
123
+
121
124
  Isolate::Scope isolate_scope(isolate);
122
125
  HandleScope handle_scope(isolate);
123
-
124
126
  TryCatch trycatch(isolate);
125
-
126
127
  Local<Context> context = eval_params->context_info->context->Get(isolate);
127
128
  Context::Scope context_scope(context);
128
129
 
@@ -135,6 +136,7 @@ nogvl_context_eval(void* arg) {
135
136
  result->parsed = !parsed_script.IsEmpty();
136
137
  result->executed = false;
137
138
  result->terminated = false;
139
+ result->json = false;
138
140
  result->value = NULL;
139
141
 
140
142
  if (!result->parsed) {
@@ -147,9 +149,36 @@ nogvl_context_eval(void* arg) {
147
149
  result->executed = !maybe_value.IsEmpty();
148
150
 
149
151
  if (result->executed) {
150
- Persistent<Value>* persistent = new Persistent<Value>();
151
- persistent->Reset(isolate, maybe_value.ToLocalChecked());
152
- result->value = persistent;
152
+
153
+ // arrays and objects get converted to json
154
+ Local<Value> local_value = maybe_value.ToLocalChecked();
155
+ if ((local_value->IsObject() || local_value->IsArray()) &&
156
+ !local_value->IsDate() && !local_value->IsFunction()) {
157
+ Local<Object> JSON = context->Global()->Get(
158
+ String::NewFromUtf8(isolate, "JSON"))->ToObject();
159
+
160
+ Local<Function> stringify = JSON->Get(v8::String::NewFromUtf8(isolate, "stringify"))
161
+ .As<Function>();
162
+
163
+ Local<Object> object = local_value->ToObject();
164
+ const unsigned argc = 1;
165
+ Local<Value> argv[argc] = { object };
166
+ MaybeLocal<Value> json = stringify->Call(JSON, argc, argv);
167
+
168
+ if (json.IsEmpty()) {
169
+ result->executed = false;
170
+ } else {
171
+ result->json = true;
172
+ Persistent<Value>* persistent = new Persistent<Value>();
173
+ persistent->Reset(isolate, json.ToLocalChecked());
174
+ result->value = persistent;
175
+ }
176
+
177
+ } else {
178
+ Persistent<Value>* persistent = new Persistent<Value>();
179
+ persistent->Reset(isolate, local_value);
180
+ result->value = persistent;
181
+ }
153
182
  }
154
183
  }
155
184
 
@@ -190,6 +219,7 @@ nogvl_context_eval(void* arg) {
190
219
 
191
220
  static VALUE convert_v8_to_ruby(Isolate* isolate, Handle<Value> &value) {
192
221
 
222
+ Isolate::Scope isolate_scope(isolate);
193
223
  HandleScope scope(isolate);
194
224
 
195
225
  if (value->IsNull() || value->IsUndefined()){
@@ -239,11 +269,10 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Handle<Value> &value) {
239
269
  }
240
270
 
241
271
  if (value->IsObject()) {
242
-
243
- TryCatch trycatch(isolate);
244
-
245
272
  VALUE rb_hash = rb_hash_new();
273
+ TryCatch trycatch(isolate);
246
274
  Local<Context> context = Context::New(isolate);
275
+
247
276
  Local<Object> object = value->ToObject();
248
277
  MaybeLocal<Array> maybe_props = object->GetOwnPropertyNames(context);
249
278
  if (!maybe_props.IsEmpty()) {
@@ -486,8 +515,6 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
486
515
  Data_Get_Struct(self, ContextInfo, context_info);
487
516
  Isolate* isolate = context_info->isolate_info->isolate;
488
517
 
489
-
490
-
491
518
  {
492
519
  Locker lock(isolate);
493
520
  Isolate::Scope isolate_scope(isolate);
@@ -553,14 +580,21 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
553
580
  }
554
581
  }
555
582
 
556
- // New scope for return value, must release GVL which
583
+ // New scope for return value
557
584
  {
558
585
  Locker lock(isolate);
559
586
  Isolate::Scope isolate_scope(isolate);
560
587
  HandleScope handle_scope(isolate);
561
588
 
562
589
  Local<Value> tmp = Local<Value>::New(isolate, *eval_result.value);
563
- result = convert_v8_to_ruby(isolate, tmp);
590
+
591
+ if (eval_result.json) {
592
+ Local<String> rstr = tmp->ToString();
593
+ VALUE json_string = rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
594
+ result = rb_funcall(rb_mJSON, rb_intern("parse"), 1, json_string);
595
+ } else {
596
+ result = convert_v8_to_ruby(isolate, tmp);
597
+ }
564
598
 
565
599
  eval_result.value->Reset();
566
600
  delete eval_result.value;
@@ -892,6 +926,7 @@ extern "C" {
892
926
  rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eStandardError);
893
927
  rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eStandardError);
894
928
  rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
929
+ rb_mJSON = rb_define_module("JSON");
895
930
 
896
931
  VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
897
932
  rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
data/lib/mini_racer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "mini_racer/version"
2
2
  require "mini_racer_extension"
3
3
  require "thread"
4
+ require "json"
4
5
 
5
6
  module MiniRacer
6
7
 
@@ -1,3 +1,3 @@
1
1
  module MiniRacer
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-06 00:00:00.000000000 Z
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler