Skip to content

Commit

Permalink
Increase performance of nested queries
Browse files Browse the repository at this point in the history
With nested queries the code was switching on the option so that it
could display a custom message. This was causing a massive increase in
compilation time as the queries got deeper and wider. In my project we
were seeing build times of about 6 minutes, after this change the build
went down to about 10-11 seconds.

Instead of displaying a custom message, the PPX will now just call out
to `Js.Option.getExn`.
  • Loading branch information
John Haley committed Oct 16, 2019
1 parent c7fab6c commit 2e17ed6
Showing 1 changed file with 79 additions and 93 deletions.
172 changes: 79 additions & 93 deletions src/bucklescript/output_bucklescript_decoder.re
Original file line number Diff line number Diff line change
Expand Up @@ -202,22 +202,14 @@ and generate_nullable_decoder = (config, loc, inner) =>
and generate_array_decoder = (config, loc, inner) =>
[@metaloc loc]
{
switch%expr (Js.Json.decodeArray(value)) {
| None =>
%e
make_error_raiser(
[%expr "Expected array, got " ++ Js.Json.stringify(value)],
)
| Some(value) =>
Js.Array.map(
value => {
let _ = ();
%e
generate_decoder(config, inner);
},
value,
)
};
%expr
value
|> Js.Json.decodeArray
|> Js.Option.getExn
|> Js.Array.map(value => {
%e
generate_decoder(config, inner)
});
}
and generate_custom_decoder = (config, loc, ident, inner) => {
let fn_expr =
Expand Down Expand Up @@ -374,89 +366,83 @@ and generate_object_decoder = (config, loc, name, fields) => {
make_obj_constructor_fn(i + 1, next),
);
[@metaloc loc]
(
switch%expr (Js.Json.decodeObject(value)) {
| None =>
%e
make_error_raiser([%expr "Object is not a value"])
| Some(value) =>
%e
Ast_helper.Exp.letmodule(
{txt: "GQL", loc: Location.none},
Ast_helper.Mod.structure([
Ast_helper.Str.primitive({
pval_name: {
txt: "make_obj",
loc: Location.none,
},
pval_type: make_obj_constructor_fn(0, fields),
pval_prim: [""],
pval_attributes: [
({txt: "bs.obj", loc: Location.none}, PStr([])),
],
pval_loc: Location.none,
}),
]),
Ast_helper.Exp.apply(
Ast_helper.Exp.ident({
txt: Longident.parse("GQL.make_obj"),
{
let%expr value = value |> Js.Json.decodeObject |> Js.Option.getExn;

%e
Ast_helper.Exp.letmodule(
{txt: "GQL", loc: Location.none},
Ast_helper.Mod.structure([
Ast_helper.Str.primitive({
pval_name: {
txt: "make_obj",
loc: Location.none,
}),
List.append(
fields
|> List.map(
fun
| Fr_named_field(key, _, inner) => (
},
pval_type: make_obj_constructor_fn(0, fields),
pval_prim: [""],
pval_attributes: [
({txt: "bs.obj", loc: Location.none}, PStr([])),
],
pval_loc: Location.none,
}),
]),
Ast_helper.Exp.apply(
Ast_helper.Exp.ident({
txt: Longident.parse("GQL.make_obj"),
loc: Location.none,
}),
List.append(
fields
|> List.map(
fun
| Fr_named_field(key, _, inner) => (
Labelled(key),
switch%expr (Js.Dict.get(value, [%e const_str_expr(key)])) {
| Some(value) =>
%e
generate_decoder(config, inner)
| None =>
if%e (can_be_absent_as_field(inner)) {
%expr
None;
} else {
make_error_raiser(
[%expr
"Field "
++ [%e const_str_expr(key)]
++ " on type "
++ [%e const_str_expr(name)]
++ " is missing"
],
);
}
},
)
| Fr_fragment_spread(key, loc, name) => {
let loc = conv_loc(loc);
(
Labelled(key),
switch%expr (
Js.Dict.get(value, [%e const_str_expr(key)])
) {
| Some(value) =>
{
let%expr value = Js.Json.object_(value);
%e
generate_decoder(config, inner)
| None =>
if%e (can_be_absent_as_field(inner)) {
%expr
None;
} else {
make_error_raiser(
[%expr
"Field "
++ [%e const_str_expr(key)]
++ " on type "
++ [%e const_str_expr(name)]
++ " is missing"
],
);
}
generate_solo_fragment_spread(loc, name);
},
)
| Fr_fragment_spread(key, loc, name) => {
let loc = conv_loc(loc);
(
Labelled(key),
{
let%expr value = Js.Json.object_(value);
%e
generate_solo_fragment_spread(loc, name);
},
);
},
),
[
(
Nolabel,
Ast_helper.Exp.construct(
{txt: Longident.Lident("()"), loc: Location.none},
None,
),
);
},
),
[
(
Nolabel,
Ast_helper.Exp.construct(
{txt: Longident.Lident("()"), loc: Location.none},
None,
),
],
),
),
],
),
)
}
);
),
);
};
}
and generate_poly_variant_selection_set = (config, loc, name, fields) => {
let rec generator_loop =
Expand Down

0 comments on commit 2e17ed6

Please sign in to comment.