From 05a890e47630b060b2aa240d82d2f2321ea829ab Mon Sep 17 00:00:00 2001 From: andrew blinn Date: Wed, 13 Nov 2024 21:37:59 -0500 Subject: [PATCH 1/3] basic parsing benchmark --- src/web/Data.re | 101 +++++++++++++++++++++++++++++++++ src/web/Store.re | 118 ++++++++++++++++++++++++++++++++------- src/web/update/Update.re | 5 +- src/web/util/TimeUtil.re | 53 ++++++++++++++++++ 4 files changed, 254 insertions(+), 23 deletions(-) create mode 100644 src/web/util/TimeUtil.re diff --git a/src/web/Data.re b/src/web/Data.re index 39d27a22..35feb61d 100644 --- a/src/web/Data.re +++ b/src/web/Data.re @@ -380,4 +380,105 @@ in update(init, StampEmoji) +|}; + +let longlong = {|let x = 1 in +let y = 2 in + +let x = 1 + 1 in +let y = 2 * 1 + 3 < 56 * 3455 - 345442 in +type Emoji = Smile + Frown + Smirk in +type Cell = Empty + Stamped(Emoji) in +type Model = ([[Cell]], Emoji) in +type Action = + StampEmoji(Int, Int) + + ClearCell(Int, Int) + + SelectEmoji(Emoji) +in +let init: Model = ( + [[None, None, None], + [None, None, None], + [None, None, None]], + Smile) +in +let update_grid: (Int, Int, Cell, [[Cell]]) -> [[Cell]] = + fun (row, col, cell, grid) -> + update_nth(row, update_nth(col, cell, List.nth(row, grid)), grid) +in +let update: (Model, Action) -> Model = + fun ((cells, selected), action) -> + case action + | StampEmoji(row, col) => + (update_grid(row, col, Stamped(Smile), cells), selected) + | ClearCell(row, col) => + (update_grid(row, col, Empty, cells), selected) + | SelectEmoji(new) => (cells, new) + end +in + +type Point = (Int, Int) in +type Rect = (Point, Int, Int) in +type Circ = (Point, Int) in +type Shape = R(Rect) + C(Circ) in +let contains = fun (s: Shape, p: Point) -> + let (x, y) = p in + case s + | R(((x_min, y_min), x_len, y_len)) => + x_min <= x && x <= x_min + x_len + && y_min <= y && y <= y_min + y_len + | C((center, r)) => dist(center, p) <= r + end +in + +type Point = (Int, Int) in +type Rect = (Point, Int, Int) in +let contains = fun (r: Rect, p: Point) -> + let (x, y) = p in + let ((x_min, y_min), x_len, y_len) = r in + x_min <= x && x <= x_min + x_len + && y_min <= y && y <= y_min + y_len +in + +let blah = shapes +|> filter(fun shape -> area(shape) < 50) +|> map(dilate(5)) +|> map(rotate(pi / 4)) +|> map(translate(6, 7)) in + +let blah = shapes +|> map(rotate(pi / 4)) +|> map(translate(6, 7)) +|> filter(fun shape -> area(shape) < 50) +|> map(dilate(5)) in + +let f = fun (square, p1, p2) -> +let mark = +fun center -> +if square then +let (x, y) = center in +rect(x - 2, y - 2, 4, 4) +else +let r = 4 in +circle(center, r) +in +[mark(p1), line(p1, p2), mark(p2)] in + +let f = fun (p1, p2) -> +let mark = +fun center -> +let r = 4 in +circle(center, r) +in +[mark(p1), line(p1, p2), mark(p2)] in + +let dist = +fun (p1, p2) -> +let (x1, y1) = p1 in +let (x2, y2) = p2 in +sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)) +in +let f = fun (center, p) -> +let r = dist(center, p) in +circle(center, r) in + |}; diff --git a/src/web/Store.re b/src/web/Store.re index e58f329e..5d4f9db2 100644 --- a/src/web/Store.re +++ b/src/web/Store.re @@ -25,27 +25,27 @@ let save_syntax_key: int => string = let save_syntax = (save_idx: int, z: Zipper.t) => LocalStorage.set(save_syntax_key(save_idx), z |> serialize); -let tasks = [ - //Data.epzz, - // Data.epz0, - // Data.epz1, - // Data.epz2, - // Data.epz3, - // Data.epz4, - //Data.t0_transcribe, - Data.t1_transcribe, - Data.t2_transcribe, - Data.t3_transcribe, - Data.t4_transcribe, - // Data.emoji_paint, - // Data.t0_modify, - // Data.t1_modify, - // Data.t2_modify, - // Data.t3_modify, - // (("case 7\n| x => 7")), - // (("let (a, b) =\n(8*9<6, 17==6) in\n(a,(a, b))")), - // (("let f = fun z -> 9 in f(9)")), -]; +let tasks = []; //Data.longlong, +//Data.epzz, +// Data.epz0, +// Data.epz1, +// Data.epz2, +// Data.epz3, +// Data.epz4, +//Data.t0_transcribe, +// Data.t1_transcribe, +// Data.t2_transcribe, +// Data.t3_transcribe, +// Data.t4_transcribe, +// Data.emoji_paint, +// Data.t0_modify, +// Data.t1_modify, +// Data.t2_modify, +// Data.t3_modify, +// (("case 7\n| x => 7")), +// (("let (a, b) =\n(8*9<6, 17==6) in\n(a,(a, b))")), + +// (("let f = fun z -> 9 in f(9)")), let editor_defaults = [serialize(Zipper.empty)] @@ -69,3 +69,79 @@ let load_syntax: int => Zipper.t = }; //let unparse: Zipper.t => string = z => z |> Zipper.zip |> Cell.tokens; + +/* given base program string Data.longlong, figure out how many copies to concatenate + to get a program of the provided number of lines, do that concat, and then trim to the exact line count. + */ +let get_program_string_of_length = (program_str, num_lines: int): string => { + let base_lines = program_str |> String.split_on_char('\n'); + let base_num_lines = base_lines |> List.length; + let num_copies = num_lines / base_num_lines; + let remainder = num_lines mod base_num_lines + 1; + let program = String.concat("\n", List.init(num_copies, _ => program_str)); + let program = + program + ++ String.concat("\n", fst(Stds.Lists.split_n(base_lines, remainder))); + program; +}; + +let benchmark = progam_str => + Util.TimeUtil.get_time(() => progam_str |> parse |> ignore); + +let time_per_line = (lines: int, time: int): float => { + float_of_int(time) /. float_of_int(lines); +}; + +let suite = () => { + let program_str = Data.longlong; + print_endline( + "BENCHMARK: parsing (prefix of) complete program with no internal obligations", + ); + let num_tokens = Labeler.label(program_str) |> List.length; + let num_chars = program_str |> String.length; + let num_lines = program_str |> String.split_on_char('\n') |> List.length; + print_endline( + "BENCHMARK: base program consists of " + ++ string_of_int(num_lines) + ++ " lines, " + ++ string_of_int(num_chars) + ++ " chars, and " + ++ string_of_int(num_tokens) + ++ " tokens", + ); + print_endline( + "BENCHMARK: Average tokens per line: " + ++ string_of_float(float_of_int(num_tokens) /. float_of_int(num_lines)), + ); + print_endline( + "BENCHMARK: Average chars per line: " + ++ string_of_float(float_of_int(num_chars) /. float_of_int(num_lines)), + ); + let a = benchmark(program_str); + print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); + let b = benchmark(program_str); + print_endline( + "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", + ); + for (i in 1 to 20) { + let num_lines = 30 * i; + let program_str = get_program_string_of_length(program_str, num_lines); + let c = benchmark(program_str); + print_endline( + "ITERATION " + ++ string_of_int(i) + ++ " :" + ++ string_of_int(num_lines) + ++ " lines. parsed in " + ++ string_of_int(c) + ++ "ms", + ); + // print_endline( + // "time per line: " + // ++ string_of_float(time_per_line(num_lines, c)) + // ++ "ms", + // ); + }; +}; + +suite(); diff --git a/src/web/update/Update.re b/src/web/update/Update.re index 6ff447b3..62140039 100644 --- a/src/web/update/Update.re +++ b/src/web/update/Update.re @@ -44,8 +44,9 @@ let handle_key_event = (k: Util.Key.t, ~model as _: Model.t): list(t) => { // | "Alt" => [SetShowBackpackTargets(false)] // | _ => [UpdateDoubleTap(None)] // } - | {key: D(key), sys: _, shift: Down, meta: Up, ctrl: Up, alt: Up} + | {key: D(key), sys: _, shift: Down | Up, meta: Up, ctrl: Up, alt: Up} when is_f_key(key) => + print_endline("F key pressed: " ++ key); if (key == "F12") { print_endline("Catch exceptions: " ++ string_of_bool(! catch_exns^)); catch_exns := ! catch_exns^; @@ -54,7 +55,7 @@ let handle_key_event = (k: Util.Key.t, ~model as _: Model.t): list(t) => { let index = int_of_string(String.sub(key, 1, 1)) - 1; print_endline("F key pressed: index: " ++ string_of_int(index)); now_save_u(Load(index)); - } + }; | {key: D(key), sys: _, shift, meta: Up, ctrl: Up, alt: Up} => switch (shift, key) { | (Up, "ArrowLeft") => now(Move(Step(H(L)))) diff --git a/src/web/util/TimeUtil.re b/src/web/util/TimeUtil.re new file mode 100644 index 00000000..467c937a --- /dev/null +++ b/src/web/util/TimeUtil.re @@ -0,0 +1,53 @@ +let print_time_prefix = + (name: string, start_time: float, end_time: float): unit => { + Printf.printf( + "%-32s%4.0fms", + name ++ ":", + 1000.0 *. (end_time -. start_time), + ); +}; + +let print_time = (name: string, start_time: float, end_time: float): unit => { + print_time_prefix(name, start_time, end_time); + Printf.printf("\n%!"); +}; + +let int_time = (start_time: float, end_time: float): int => { + int_of_float(1000.0 *. (end_time -. start_time)); +}; + +let print_times = + (name: string, start_time: float, times: list((string, float))): unit => { + assert(times != []); + let end_time = List.fold_left((_, last) => snd(last), -1.0, times); + print_time_prefix(name, start_time, end_time); + Printf.printf(" ["); + let rec go = (previous_time: float, times: list((string, float))): unit => { + switch (times) { + | [] => () + | [(name, time), ...times] => + Printf.printf(" %s: %.0fms", name, 1000.0 *. (time -. previous_time)); + go(time, times); + }; + }; + go(start_time, times); + Printf.printf(" ]\n%!"); +}; + +let measure_time = (name: string, measure: bool, f: unit => 'a): 'a => + if (measure) { + let start_time = Sys.time(); + let x = f(); + let end_time = Sys.time(); + print_time(name, start_time, end_time); + x; + } else { + f(); + }; + +let get_time = (f: unit => 'a): int => { + let start_time = Sys.time(); + let _ = f(); + let end_time = Sys.time(); + int_time(start_time, end_time); +}; From edd315491ea1207867c73577e9d8e2dbe14870a1 Mon Sep 17 00:00:00 2001 From: disconcision Date: Thu, 14 Nov 2024 16:13:30 -0500 Subject: [PATCH 2/3] edit action insertion benchmark --- src/core/editor/Zipper.re | 7 ++ src/web/Benchmark.re | 135 ++++++++++++++++++++++++++++++++++++++ src/web/Data.re | 101 ++++++++++++++++++++++++++++ src/web/Store.re | 80 +--------------------- src/web/update/Update.re | 6 +- 5 files changed, 249 insertions(+), 80 deletions(-) create mode 100644 src/web/Benchmark.re diff --git a/src/core/editor/Zipper.re b/src/core/editor/Zipper.re index 070b7300..0d44730b 100644 --- a/src/core/editor/Zipper.re +++ b/src/core/editor/Zipper.re @@ -303,3 +303,10 @@ let selection_str = (cur: Cursor.Base.t('tok)): option(string) => |> String.concat("") |> Option.some }; + +let to_string = (z: t): string => { + zip(z) + |> Cell.flatten + |> List.map((x: Token.t) => x.text) + |> String.concat(""); +}; diff --git a/src/web/Benchmark.re b/src/web/Benchmark.re new file mode 100644 index 00000000..a6570a5e --- /dev/null +++ b/src/web/Benchmark.re @@ -0,0 +1,135 @@ +open Tylr_core; + +/* given base program string, figure out how many copies to concatenate + to get a program of the provided number of lines, do that concat, and then trim to the exact line count. + */ +let get_program_string_of_length = (program_str, num_lines: int): string => { + let base_lines = program_str |> String.split_on_char('\n'); + let base_num_lines = base_lines |> List.length; + let num_copies = num_lines / base_num_lines; + let remainder = num_lines mod base_num_lines + 1; + let program = String.concat("\n", List.init(num_copies, _ => program_str)); + let program = + program + ++ String.concat("\n", fst(Stds.Lists.split_n(base_lines, remainder))); + program; +}; + +let benchmark = progam_str => + Util.TimeUtil.get_time(() => progam_str |> Store.parse |> ignore); + +let time_per_line = (lines: int, time: int): float => { + float_of_int(time) /. float_of_int(lines); +}; + +let benchmark_parsing = () => { + let program_str = Data.longlong; + print_endline( + "BENCHMARK: parsing (prefix of) complete program with no internal obligations", + ); + let num_tokens = Labeler.label(program_str) |> List.length; + let num_chars = program_str |> String.length; + let num_lines = program_str |> String.split_on_char('\n') |> List.length; + print_endline( + "BENCHMARK: base program consists of " + ++ string_of_int(num_lines) + ++ " lines, " + ++ string_of_int(num_chars) + ++ " chars, and " + ++ string_of_int(num_tokens) + ++ " tokens", + ); + print_endline( + "BENCHMARK: Average tokens per line: " + ++ string_of_float(float_of_int(num_tokens) /. float_of_int(num_lines)), + ); + print_endline( + "BENCHMARK: Average chars per line: " + ++ string_of_float(float_of_int(num_chars) /. float_of_int(num_lines)), + ); + let a = benchmark(program_str); + print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); + let b = benchmark(program_str); + print_endline( + "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", + ); + for (i in 1 to 20) { + let num_lines = 30 * i; + let program_str = get_program_string_of_length(program_str, num_lines); + let c = benchmark(program_str); + print_endline( + "ITERATION " + ++ string_of_int(i) + ++ " :" + ++ string_of_int(num_lines) + ++ " lines. parsed in " + ++ string_of_int(c) + ++ "ms", + ); + // print_endline( + // "time per line: " + // ++ string_of_float(time_per_line(num_lines, c)) + // ++ "ms", + // ); + }; +}; + +let cursor_depth = (z: Zipper.t) => { + let cell = Zipper.zip(~save_cursor=true, z); + switch (cell.marks.cursor) { + | Some(Point(cursor)) => cursor.path |> List.length + | _ => failwith("benchmark: no cursor") + }; +}; + +let benchmark_hole_fills = () => { + let program_str = Data.holey; + let reps_per_action = 200; + let zipper_action = Modify.insert("X"); + + print_endline("BENCHMARK: filling hole edits at different depths"); + let a = benchmark(program_str); + print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); + let b = benchmark(program_str); + print_endline( + "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", + ); + let z = + List.fold_left( + (z_acc, _x) => { + // perform insertion action repeatedly + let t = + Util.TimeUtil.get_time(() => { + for (_ in 1 to reps_per_action) { + let _ = zipper_action(z_acc); + (); + } + }); + print_endline( + "depth: " + ++ string_of_int(cursor_depth(z_acc)) + ++ ", " + ++ "time for " + ++ string_of_int(reps_per_action) + ++ " insertions:" + ++ string_of_int(t) + ++ "ms", + ); + // fill hole and return zipper with caret moved to previous hole + let z2 = Modify.insert("X", z_acc); + switch (Tab.perform(L, z2)) { + | None => z2 + | Some(z3) => z3 + }; + }, + // starts at bottom of holey program + Store.parse(program_str), + List.init(20, _ => ()), + ); + (); + print_endline("program after actions:"); + print_endline(z |> Zipper.to_string); +}; + +//benchmark_parsing(); +benchmark_hole_fills(); diff --git a/src/web/Data.re b/src/web/Data.re index 35feb61d..d95029f1 100644 --- a/src/web/Data.re +++ b/src/web/Data.re @@ -482,3 +482,104 @@ let r = dist(center, p) in circle(center, r) in |}; + +let holey = {|let x = + 1 in +let y = 2 in + +let x = 1 + 1 in +let y = 2 * 1 + 3 < 56 * + 345442 in +type Emoji = Smile + Frown + Smirk in +type Cell = Empty + Stamped(Emoji) in +type Model = ([[ ]], Emoji) in +type Action = + StampEmoji(Int, Int) + + ClearCell(Int, Int) + + SelectEmoji(Emoji) +in +let init: Model = ( + [[None, None, None], + [None, None, None], + [None, None, ]], + Smile) +in +let update_grid: (Int, Int, Cell, [[Cell]]) -> [[Cell]] = + fun (row, col, cell, grid) -> + update_nth(row, update_nth(col, cell, List.nth(row, grid)), grid) +in +let update: (Model, Action) -> Model = + fun ((cells, selected), action) -> + case action + | StampEmoji(row, col) => + (update_grid(row, , Stamped(Smile), cells), selected) + | ClearCell(row, col) => + (update_grid(row, col, Empty, cells), selected) + | SelectEmoji( ) => (cells, new) + end +in + +type Point = (Int, Int) in +type Rect = (Point, Int, Int) in +type Circ = (Point, Int) in +type Shape = R(Rect) + C(Circ) in +let contains = fun ( , p: Point) -> + let (x, y) = p in + case s + | R(((x_min, y_min), x_len, y_len)) => + <= x && x <= x_min + x_len + && y_min <= y && y <= y_min + + | C((center, r)) => dist(center, p) <= r + end +in + +type Point = (Int, Int) in +type Rect = (Point, Int, Int) in +let contains = fun (r: Rect, p: Point) -> + let (x, y) = p in + let ((x_min, y_min), x_len, y_len) = r in + x_min <= x && x <= x_min + x_len + && y_min <= y && y <= y_min + y_len +in + +let blah = shapes +|> filter(fun shape -> area(shape) < 50) +|> map(dilate(5)) +|> map(rotate( / 4)) +|> map(translate(6, 7)) in + +let blah = shapes +|> map(rotate(pi / 4)) +|> map(translate(, 7)) +|> filter(fun shape -> area( ) < 50) +|> map(dilate(5)) in + +let f = fun (square, p1, p2) -> +let = +fun center -> +if square then +let (x, y) = center in +rect(x - 2, y - 2, 4, ) +else +let r = 4 in +circle(center, ) +in +[mark(p1), line(p1, p2), mark(p2)] in + +let f = fun (p1, p2) -> +let mark = +fun center -> +let r = 4 in +circle(center, ) +in +[mark(p1), line(p1, p2), mark(p2)] in + +let dist = +fun (p1, p2) -> +let (x1, ) = p1 in +let (x2, y2) = p2 in +sqrt(pow(x1 - x2, 2) + pow(y1 - y2, )) +in +let f = fun (center, p) -> +let r = dist(center, p) in +circle( , r) in + +|}; diff --git a/src/web/Store.re b/src/web/Store.re index 5d4f9db2..77f91834 100644 --- a/src/web/Store.re +++ b/src/web/Store.re @@ -25,7 +25,7 @@ let save_syntax_key: int => string = let save_syntax = (save_idx: int, z: Zipper.t) => LocalStorage.set(save_syntax_key(save_idx), z |> serialize); -let tasks = []; //Data.longlong, +let tasks = [Data.holey]; //Data.longlong, //Data.epzz, // Data.epz0, // Data.epz1, @@ -67,81 +67,3 @@ let load_syntax: int => Zipper.t = | None => load_default_syntax(save_idx) | Some(str) => deserialize(str) }; - -//let unparse: Zipper.t => string = z => z |> Zipper.zip |> Cell.tokens; - -/* given base program string Data.longlong, figure out how many copies to concatenate - to get a program of the provided number of lines, do that concat, and then trim to the exact line count. - */ -let get_program_string_of_length = (program_str, num_lines: int): string => { - let base_lines = program_str |> String.split_on_char('\n'); - let base_num_lines = base_lines |> List.length; - let num_copies = num_lines / base_num_lines; - let remainder = num_lines mod base_num_lines + 1; - let program = String.concat("\n", List.init(num_copies, _ => program_str)); - let program = - program - ++ String.concat("\n", fst(Stds.Lists.split_n(base_lines, remainder))); - program; -}; - -let benchmark = progam_str => - Util.TimeUtil.get_time(() => progam_str |> parse |> ignore); - -let time_per_line = (lines: int, time: int): float => { - float_of_int(time) /. float_of_int(lines); -}; - -let suite = () => { - let program_str = Data.longlong; - print_endline( - "BENCHMARK: parsing (prefix of) complete program with no internal obligations", - ); - let num_tokens = Labeler.label(program_str) |> List.length; - let num_chars = program_str |> String.length; - let num_lines = program_str |> String.split_on_char('\n') |> List.length; - print_endline( - "BENCHMARK: base program consists of " - ++ string_of_int(num_lines) - ++ " lines, " - ++ string_of_int(num_chars) - ++ " chars, and " - ++ string_of_int(num_tokens) - ++ " tokens", - ); - print_endline( - "BENCHMARK: Average tokens per line: " - ++ string_of_float(float_of_int(num_tokens) /. float_of_int(num_lines)), - ); - print_endline( - "BENCHMARK: Average chars per line: " - ++ string_of_float(float_of_int(num_chars) /. float_of_int(num_lines)), - ); - let a = benchmark(program_str); - print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); - let b = benchmark(program_str); - print_endline( - "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", - ); - for (i in 1 to 20) { - let num_lines = 30 * i; - let program_str = get_program_string_of_length(program_str, num_lines); - let c = benchmark(program_str); - print_endline( - "ITERATION " - ++ string_of_int(i) - ++ " :" - ++ string_of_int(num_lines) - ++ " lines. parsed in " - ++ string_of_int(c) - ++ "ms", - ); - // print_endline( - // "time per line: " - // ++ string_of_float(time_per_line(num_lines, c)) - // ++ "ms", - // ); - }; -}; - -suite(); diff --git a/src/web/update/Update.re b/src/web/update/Update.re index 62140039..da20628b 100644 --- a/src/web/update/Update.re +++ b/src/web/update/Update.re @@ -218,7 +218,11 @@ let apply = // | SetLogoFont(logo_font_metrics) => // Ok({...model, logo_font_metrics}) | PerformAction(a) => - switch (Edit.perform(a, model.zipper)) { + switch ( + Util.TimeUtil.measure_time("Edit.perform", true, () => + Edit.perform(a, model.zipper) + ) + ) { | None => Error(FailedToPerform) | Some(z) => Ok({...model, zipper: z, history: History.do_(a, z, model.history)}) From c5b001a18d4eec841a33d50199aeb129f411eba3 Mon Sep 17 00:00:00 2001 From: disconcision Date: Thu, 14 Nov 2024 17:01:21 -0500 Subject: [PATCH 3/3] pre+suf length measuring --- src/web/Benchmark.re | 30 ++++++++++++++++++++---------- src/web/Data.re | 12 ++++++++++++ src/web/Main.re | 2 ++ src/web/Store.re | 2 +- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/web/Benchmark.re b/src/web/Benchmark.re index a6570a5e..986d7f56 100644 --- a/src/web/Benchmark.re +++ b/src/web/Benchmark.re @@ -74,7 +74,7 @@ let benchmark_parsing = () => { }; }; -let cursor_depth = (z: Zipper.t) => { +let cursor_depth = (z: Zipper.t): int => { let cell = Zipper.zip(~save_cursor=true, z); switch (cell.marks.cursor) { | Some(Point(cursor)) => cursor.path |> List.length @@ -82,18 +82,27 @@ let cursor_depth = (z: Zipper.t) => { }; }; +let pre_plus_suf_length = (z: Zipper.t): int => { + let ((pre, suf), _tl) = Ctx.uncons(z.ctx); + List.length(pre) + List.length(suf); +}; + let benchmark_hole_fills = () => { let program_str = Data.holey; + //let program_str = List.fold_left((++), "", List.init(40, _ => Data.base1)); + let num_holes = 20; //40 let reps_per_action = 200; let zipper_action = Modify.insert("X"); print_endline("BENCHMARK: filling hole edits at different depths"); - let a = benchmark(program_str); - print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); - let b = benchmark(program_str); - print_endline( - "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", - ); + print_endline("init program, parsed and then stringed:"); + print_endline(program_str |> Store.parse |> Zipper.to_string); + // let a = benchmark(program_str); + // print_endline("BENCHMARK: warmup parse: " ++ string_of_int(a) ++ "ms"); + // let b = benchmark(program_str); + // print_endline( + // "BENCHMARK: same parse after warmup: " ++ string_of_int(b) ++ "ms", + // ); let z = List.fold_left( (z_acc, _x) => { @@ -106,7 +115,9 @@ let benchmark_hole_fills = () => { } }); print_endline( - "depth: " + "presuf: " + ++ string_of_int(pre_plus_suf_length(z_acc)) + ++ ", depth: " ++ string_of_int(cursor_depth(z_acc)) ++ ", " ++ "time for " @@ -124,7 +135,7 @@ let benchmark_hole_fills = () => { }, // starts at bottom of holey program Store.parse(program_str), - List.init(20, _ => ()), + List.init(num_holes, _ => ()), ); (); print_endline("program after actions:"); @@ -132,4 +143,3 @@ let benchmark_hole_fills = () => { }; //benchmark_parsing(); -benchmark_hole_fills(); diff --git a/src/web/Data.re b/src/web/Data.re index d95029f1..ac9165b4 100644 --- a/src/web/Data.re +++ b/src/web/Data.re @@ -583,3 +583,15 @@ let r = dist(center, p) in circle( , r) in |}; + +let base1 = {|let = 1 in +|}; + +let base1' = base1 ++ base1 ++ base1 ++ base1 ++ base1; + +let base2 = {|let x = + 2 in +let x = + 2 * 3 in +let x = + 2 / 3 + 4 in +let x = 1 + 2 + + 4 + 5 in +let x = 1 + 2 * 3 + + 5 + 6 in +|}; diff --git a/src/web/Main.re b/src/web/Main.re index d52cb85e..19e4c49a 100644 --- a/src/web/Main.re +++ b/src/web/Main.re @@ -176,3 +176,5 @@ Incr_dom.Start_app.start( ~bind_to_element_with_id="container", ~initial_model=Model.init_from_store(), ); + +Benchmark.benchmark_hole_fills(); diff --git a/src/web/Store.re b/src/web/Store.re index 77f91834..9da93263 100644 --- a/src/web/Store.re +++ b/src/web/Store.re @@ -25,7 +25,7 @@ let save_syntax_key: int => string = let save_syntax = (save_idx: int, z: Zipper.t) => LocalStorage.set(save_syntax_key(save_idx), z |> serialize); -let tasks = [Data.holey]; //Data.longlong, +let tasks = [Data.base1']; //Data.longlong, //Data.epzz, // Data.epz0, // Data.epz1,