Commits

camlspotter committed a571376

efficient (but probably incorrect) position comparision

Comments (0)

Files changed (4)

ocaml/prof/prof_inlined2.txt

 
   x74.382845 (original 0.779917, planck 58.012428)
 
+-------- moving to observe lexer prof
+
+The following indicates lots of compare_val is called from <|> and <!>, which compare positions!
+  -----------------------------------------------
+                  0.00    0.00       1/24029544     camlRandom__full_init_1040 [269]
+                  0.02    0.08 6884802/24029544     camlPlanck__Pbase__$3c$7c$3e_2589 <cycle 1> [32]
+                  0.05    0.19 17144741/24029544     camlPlanck__Pbase__$3c$21$3e_2602 <cycle 1> [15]
+  [28]     2.7    0.07    0.26 24029544         caml_equal [28]
+                  0.26    0.00 24029544/41367650     compare_val [22]
+  -----------------------------------------------
+Added Pos.equal to check the position equality quickly.

pa_bind_inline/pa_bind_inline.ml

           let res__ = $e1$ in
           match res__ with
           | Result.Ok _ -> res__
-          | Result.Error (pos__', _) when pos__ <> pos__' -> res__
+          | Result.Error (pos__', _) when not (Str.Pos.equal pos__ pos__') -> res__
           | _ -> $e2$ >>
     | _ ->  <:expr< (<|>) $t1$ $t2$ >>
 (* It's too huge
     | Error err -> error err <?@> pos
 
   let token : Str.elem -> unit t = fun tkn ->
-    ignore (tokenp (fun x -> Str.equal_elem tkn x)) <?>  Str.show_elem tkn
+    ignore (tokenp (Str.equal_elem tkn)) <?>  Str.show_elem tkn
 
   (* CR jfuruss: optimization oppotunity for char *)     
   let one_of : Str.elem list -> Str.elem t = fun tkns ->
     let res = c1 st in
     match res with
     | Ok _ -> res
-    | Error (pos, _) -> if pos = pos0 then c2 st else res
+    | Error (pos, _) -> if Str.Pos.equal pos pos0 then c2 st else res
 
   (* CR jfuruse: _ is used in a different meaning than option_ *)
   let try_ : 'a t -> 'a t = fun c st ->
         Profile.add (Profile.stop ());
         res
     | Error (pos', _) -> 
-        if pos = pos' then Profile.add (Profile.stop ())
+        if Str.Pos.equal pos pos' then Profile.add (Profile.stop ())
         else begin
           Profile.wasted := !Profile.wasted + Profile.stop ();
         end;
         let res2 = c2 st in
         match res2 with
         | Ok _ -> 
-            if pos = pos' then Profile.add binds_in_c1
+            if Str.Pos.equal pos pos' then Profile.add binds_in_c1
             else Profile.wasted := !Profile.wasted + binds_in_c1;
             res2
         | Error (pos'', _) -> 
-            if pos' = pos'' then Profile.add (Profile.stop ())
+            if Str.Pos.equal pos' pos'' then Profile.add (Profile.stop ())
             else Profile.wasted := !Profile.wasted + Profile.stop ();
             res1
 
   val format : Format.formatter -> t -> unit
   val top : string -> t
   val none : t
+  val equal : t -> t -> bool
 end
 
 module None = struct
   let format ppf () = Format.pp_print_string ppf "<no position>"
   let top (_ : string) = ()
   let none = ()
+  let equal () () = true
 end
 
 module type File = sig
   val add_newlines : t -> int -> t
   val add_columns : t -> int -> t
   val none : t
+  val equal : t -> t -> bool
+  (** It only checks bytes for performance reason. *)
+
   val format : Format.formatter -> t -> unit
   val format_detailed : Format.formatter -> t -> unit
 end
   let format_detailed ppf t = 
     if t.byte < 0 then Format.fprintf ppf "<no location>"
     else Format.fprintf ppf "%aline %d, character %d, byte %d" format_filename t.fname t.line t.column t.byte
-
+  let equal t1 t2 = t1.byte = t2.byte
 end
 
 (* CR jfuruse: or Location, if we follow the OCaml tradition *)
 
   let top fname = { start = File.top fname; end_ = File.top fname }
   let none = { start = File.none; end_ = File.none }
+  let equal t1 t2 = File.equal t1.start t2.start && File.equal t2.end_ t2.end_
   let format ppf t = 
     if t.start.File.byte < 0 then Format.fprintf ppf "<no location>"
     else