Browse Source

[eval] make Map creation a bit faster

Simon Krajewski 7 years ago
parent
commit
efb01888ad

+ 1 - 1
src/macro/eval/evalEmitter.ml

@@ -279,7 +279,7 @@ let emit_constructor_call proto fnew execs p =
 	let vf = lazy (match Lazy.force fnew with VFunction (f,_) -> f | v -> cannot_call v p) in
 	(fun env ->
 		let f = Lazy.force vf in
-		let vthis = create_instance_direct proto in
+		let vthis = create_instance_direct proto INormal in
 		let vl = List.map (apply env) execs in
 		env.env_leave_pmin <- p.pmin;
 		env.env_leave_pmax <- p.pmax;

+ 17 - 10
src/macro/eval/evalEncode.ml

@@ -162,11 +162,11 @@ let encode_enum i pos index pl =
 
 (* Instances *)
 
-let create_instance_direct proto =
+let create_instance_direct proto kind =
 	vinstance {
 		ifields = if Array.length proto.pinstance_fields = 0 then proto.pinstance_fields else Array.copy proto.pinstance_fields;
 		iproto = proto;
-		ikind = INormal;
+		ikind = kind;
 	}
 
 let create_instance ?(kind=INormal) path =
@@ -192,17 +192,24 @@ let encode_array l =
 let encode_string s =
 	create_unknown s
 
-let encode_bytes s =
-	encode_instance key_haxe_io_Bytes ~kind:(IBytes s)
+(* Should only be used for std types that aren't expected to change while the compilation server is running *)
+let create_cached_instance path fkind =
+	let proto = lazy (get_instance_prototype (get_ctx()) path null_pos) in
+	(fun v ->
+		create_instance_direct (Lazy.force proto) (fkind v)
+	)
+
+let encode_bytes =
+	create_cached_instance key_haxe_io_Bytes (fun s -> IBytes s)
 
-let encode_int_map_direct h =
-	encode_instance key_haxe_ds_IntMap ~kind:(IIntMap h)
+let encode_int_map_direct =
+	create_cached_instance key_haxe_ds_IntMap (fun s -> IIntMap s)
 
-let encode_string_map_direct h =
-	encode_instance key_haxe_ds_StringMap ~kind:(IStringMap h)
+let encode_string_map_direct =
+	create_cached_instance key_haxe_ds_StringMap (fun s -> IStringMap s)
 
-let encode_object_map_direct h =
-	encode_instance key_haxe_ds_ObjectMap ~kind:(IObjectMap (Obj.magic h))
+let encode_object_map_direct =
+	create_cached_instance key_haxe_ds_ObjectMap (fun (s : value ValueHashtbl.t) -> IObjectMap (Obj.magic s))
 
 let encode_string_map convert m =
 	let h = StringHashtbl.create () in

+ 3 - 3
src/macro/eval/evalStdLib.ml

@@ -2878,9 +2878,9 @@ let init_constructors builtins =
 			| [size] -> encode_instance key_haxe_Utf8 ~kind:(IUtf8 (UTF8.Buf.create (default_int size 0)))
 			| _ -> assert false
 		);
-	add key_haxe_ds_StringMap (fun _ -> encode_instance key_haxe_ds_StringMap ~kind:(IStringMap (StringHashtbl.create ())));
-	add key_haxe_ds_IntMap (fun _ -> encode_instance key_haxe_ds_IntMap ~kind:(IIntMap (IntHashtbl.create ())));
-	add key_haxe_ds_ObjectMap (fun _ -> encode_instance key_haxe_ds_ObjectMap ~kind:(IObjectMap (Obj.magic (ValueHashtbl.create 0))));
+	add key_haxe_ds_StringMap (fun _ -> encode_string_map_direct (StringHashtbl.create ()));
+	add key_haxe_ds_IntMap (fun _ -> encode_int_map_direct (IntHashtbl.create ()));
+	add key_haxe_ds_ObjectMap (fun _ -> encode_object_map_direct (Obj.magic (ValueHashtbl.create 0)));
 	add key_haxe_io_BytesBuffer (fun _ -> encode_instance key_haxe_io_BytesBuffer ~kind:(IOutput (Buffer.create 0)));
 	add key_haxe_io_Bytes
 		(fun vl -> match vl with

+ 3 - 1
tests/benchs/src/cases/Access.hx

@@ -39,7 +39,9 @@ class Access extends TestCase {
 
 	@:analyzer(ignore)
 	function measureJson() {
-		var o:Obj = haxe.Json.parse(haxe.Json.stringify(getObj()));
+		var o = getObj();
+		var o = haxe.Json.stringify(o);
+		var o:Obj = haxe.Json.parse(o);
 		var suite = new Suite("json");
 		suite.add(".Int", o.i);
 		suite.add(".Float", o.f);