Skip to content

Commit 3d1241e

Browse files
hhugoOlivierNicole
authored andcommitted
Compiler: speedup json parsing, relying on Yojson.Raw (#1640)
1 parent 08316ce commit 3d1241e

File tree

3 files changed

+87
-44
lines changed

3 files changed

+87
-44
lines changed

compiler/lib/js_output.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ let program ?(accept_unnamed_var = false) f ?source_map p =
15341534
let temp_mappings = ref [] in
15351535
let files = Hashtbl.create 17 in
15361536
let names = Hashtbl.create 17 in
1537-
let contents : string option list ref option =
1537+
let contents : Source_map.Source_content.t option list ref option =
15381538
match source_map with
15391539
| None | Some { Source_map.sources_content = None; _ } -> None
15401540
| Some { Source_map.sources_content = Some _; _ } -> Some (ref [])
@@ -1577,7 +1577,13 @@ let program ?(accept_unnamed_var = false) f ?source_map p =
15771577
with Not_found ->
15781578
let pos = Hashtbl.length files in
15791579
Hashtbl.add files file pos;
1580-
Option.iter contents ~f:(fun r -> r := find_source file :: !r);
1580+
Option.iter contents ~f:(fun r ->
1581+
let source_contents =
1582+
match find_source file with
1583+
| None -> None
1584+
| Some s -> Some (Source_map.Source_content.create s)
1585+
in
1586+
r := source_contents :: !r);
15811587
pos)
15821588
, (fun name ->
15831589
try Hashtbl.find names name

compiler/lib/source_map.ml

Lines changed: 72 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919

2020
open! Stdlib
2121

22+
module Source_content = struct
23+
type t = Sc_as_Stringlit of string
24+
25+
let create s = Sc_as_Stringlit (Yojson.Safe.to_string (`String s))
26+
27+
let of_stringlit (`Stringlit s) = Sc_as_Stringlit s
28+
29+
let to_json (Sc_as_Stringlit s) = `Stringlit s
30+
end
31+
2232
type map =
2333
| Gen of
2434
{ gen_line : int
@@ -47,7 +57,7 @@ type t =
4757
; file : string
4858
; sourceroot : string option
4959
; sources : string list
50-
; sources_content : string option list option
60+
; sources_content : Source_content.t option list option
5161
; names : string list
5262
; mappings : mapping
5363
}
@@ -310,97 +320,118 @@ let json ?replace_mappings t =
310320
| Some map -> Build_path_prefix_map.rewrite map path
311321
| None -> path
312322
in
323+
let stringlit s = `Stringlit (Yojson.Safe.to_string (`String s)) in
313324
`Assoc
314-
[ "version", `Float (float_of_int t.version)
315-
; "file", `String (rewrite_path t.file)
325+
[ "version", `Intlit (string_of_int t.version)
326+
; "file", stringlit (rewrite_path t.file)
316327
; ( "sourceRoot"
317-
, `String
328+
, stringlit
318329
(match t.sourceroot with
319330
| None -> ""
320331
| Some s -> rewrite_path s) )
321-
; "names", `List (List.map t.names ~f:(fun s -> `String s))
322-
; "sources", `List (List.map t.sources ~f:(fun s -> `String (rewrite_path s)))
323-
; ( "mappings"
324-
, `String (Option.value ~default:(string_of_mapping t.mappings) replace_mappings) )
332+
; "names", `List (List.map t.names ~f:(fun s -> stringlit s))
333+
; "sources", `List (List.map t.sources ~f:(fun s -> stringlit (rewrite_path s)))
334+
; "mappings", stringlit (Option.value ~default:(string_of_mapping t.mappings) replace_mappings)
325335
; ( "sourcesContent"
326336
, `List
327337
(match t.sources_content with
328338
| None -> []
329339
| Some l ->
330340
List.map l ~f:(function
331341
| None -> `Null
332-
| Some s -> `String s)) )
342+
| Some x -> Source_content.to_json x)) )
333343
]
334344

335345
let invalid () = invalid_arg "Source_map.of_json"
336346

337-
let string name rest =
347+
let string_of_stringlit (`Stringlit s) =
348+
match Yojson.Safe.from_string s with
349+
| `String s -> s
350+
| _ -> invalid ()
351+
352+
let stringlit name rest : [ `Stringlit of string ] option =
338353
try
339354
match List.assoc name rest with
340-
| `String s -> Some s
355+
| `Stringlit _ as s -> Some s
341356
| `Null -> None
342357
| _ -> invalid ()
343358
with Not_found -> None
344359

345-
let list_string name rest =
360+
let list_stringlit name rest =
346361
try
347362
match List.assoc name rest with
348363
| `List l ->
349364
Some
350365
(List.map l ~f:(function
351-
| `String s -> s
366+
| `Stringlit _ as s -> s
352367
| _ -> invalid ()))
353368
| _ -> invalid ()
354369
with Not_found -> None
355370

356-
let list_string_opt name rest =
371+
let list_stringlit_opt name rest =
357372
try
358373
match List.assoc name rest with
359374
| `List l ->
360375
Some
361376
(List.map l ~f:(function
362-
| `String s -> Some s
377+
| `Stringlit _ as s -> Some s
363378
| `Null -> None
364379
| _ -> invalid ()))
365380
| _ -> invalid ()
366381
with Not_found -> None
367382

368-
let of_json ~parse_mappings json =
369-
let parse ~version rest =
370-
let def v d =
371-
match v with
372-
| None -> d
373-
| Some v -> v
383+
let of_json ~parse_mappings (json : Yojson.Raw.t) =
384+
match json with
385+
| `Assoc (("version", `Intlit version) :: rest) when int_of_string version = 3 ->
386+
let string name json = Option.map ~f:string_of_stringlit (stringlit name json) in
387+
let file =
388+
match string "file" rest with
389+
| None -> ""
390+
| Some s -> s
374391
in
375-
let file = string "file" rest in
376392
let sourceroot = string "sourceRoot" rest in
377-
let names = list_string "names" rest in
378-
let sources = list_string "sources" rest in
379-
let sources_content = list_string_opt "sourcesContent" rest in
380-
let mappings = string "mappings" rest in
381-
( { version
382-
; file = def file ""
393+
let names =
394+
match list_stringlit "names" rest with
395+
| None -> []
396+
| Some l -> List.map ~f:string_of_stringlit l
397+
in
398+
let sources =
399+
match list_stringlit "sources" rest with
400+
| None -> []
401+
| Some l -> List.map ~f:string_of_stringlit l
402+
in
403+
let sources_content =
404+
match list_stringlit_opt "sourcesContent" rest with
405+
| None -> None
406+
| Some l ->
407+
Some
408+
(List.map l ~f:(function
409+
| None -> None
410+
| Some s -> Some (Source_content.of_stringlit s)))
411+
in
412+
let mappings =
413+
match string "mappings" rest with
414+
| None -> mapping_of_string ""
415+
| Some s -> mapping_of_string s
416+
in
417+
( { version = int_of_float (float_of_string version)
418+
; file
383419
; sourceroot
384-
; names = def names []
420+
; names
385421
; sources_content
386-
; sources = def sources []
387-
; mappings = mapping_of_string (def mappings "")
422+
; sources
423+
; mappings
388424
}
389-
, if parse_mappings then None else mappings )
390-
in
391-
match json with
392-
| `Assoc (("version", `Float version) :: rest) when int_of_float version = 3 ->
393-
parse ~version:3 rest
394-
| `Assoc (("version", `Int 3) :: rest) -> parse ~version:3 rest
425+
, if parse_mappings then None else Some mappings )
395426
| _ -> invalid ()
396427

397-
let of_string s = of_json ~parse_mappings:true (Yojson.Basic.from_string s) |> fst
428+
let of_string s = of_json ~parse_mappings:true (Yojson.Raw.from_string s) |> fst
398429

399-
let to_string m = Yojson.Basic.to_string (json m)
430+
let to_string m = Yojson.Raw.to_string (json m)
400431

401432
let to_file ?mappings m ~file =
402433
let replace_mappings = mappings in
403-
Yojson.Basic.to_file file (json ?replace_mappings m)
434+
Yojson.Raw.to_file file (json ?replace_mappings m)
404435

405436
let of_file_no_mappings filename =
406-
of_json ~parse_mappings:false (Yojson.Basic.from_file filename)
437+
of_json ~parse_mappings:false (Yojson.Raw.from_file filename)

compiler/lib/source_map.mli

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1818
*)
1919

20+
module Source_content : sig
21+
type t
22+
23+
val create : string -> t
24+
end
25+
2026
type map =
2127
| Gen of
2228
{ gen_line : int
@@ -45,7 +51,7 @@ type t =
4551
; file : string
4652
; sourceroot : string option
4753
; sources : string list
48-
; sources_content : string option list option
54+
; sources_content : Source_content.t option list option
4955
; names : string list
5056
; mappings : mapping
5157
}

0 commit comments

Comments
 (0)