move if statement that only needs to be checked once from helpBinSearch, which is recursive, to binSearch which is not recursive, for negligibly better performance (fewer branch predictions)
This commit is contained in:
235
src/line_gap.sml
235
src/line_gap.sml
@@ -2,34 +2,34 @@ structure LineGap =
|
|||||||
struct
|
struct
|
||||||
local
|
local
|
||||||
fun helpCountLineBreaks (pos, acc, str) =
|
fun helpCountLineBreaks (pos, acc, str) =
|
||||||
let
|
let
|
||||||
val _ = print ("count pos: " ^ Int.toString pos ^ "\n")
|
val _ = print ("count pos: " ^ Int.toString pos ^ "\n")
|
||||||
in
|
in
|
||||||
if pos < 0 then
|
if pos < 0 then
|
||||||
Vector.fromList acc
|
Vector.fromList acc
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val chr = String.sub (str, pos)
|
val chr = String.sub (str, pos)
|
||||||
in
|
in
|
||||||
if chr = #"\n" then
|
if chr = #"\n" then
|
||||||
(* Is this a \r\n pair? Then the position of \r should be consed. *)
|
(* Is this a \r\n pair? Then the position of \r should be consed. *)
|
||||||
if pos = 0 then
|
if pos = 0 then
|
||||||
Vector.fromList (0 :: acc)
|
Vector.fromList (0 :: acc)
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val prevChar = String.sub (str, pos - 1)
|
||||||
|
in
|
||||||
|
if prevChar = #"\r" then
|
||||||
|
helpCountLineBreaks (pos - 2, (pos - 1) :: acc, str)
|
||||||
|
else
|
||||||
|
helpCountLineBreaks (pos - 2, pos :: acc, str)
|
||||||
|
end
|
||||||
|
else if chr = #"\r" then
|
||||||
|
helpCountLineBreaks (pos - 1, pos :: acc, str)
|
||||||
else
|
else
|
||||||
let
|
helpCountLineBreaks (pos - 1, acc, str)
|
||||||
val prevChar = String.sub (str, pos - 1)
|
end
|
||||||
in
|
end
|
||||||
if prevChar = #"\r" then
|
|
||||||
helpCountLineBreaks (pos - 2, (pos - 1) :: acc, str)
|
|
||||||
else
|
|
||||||
helpCountLineBreaks (pos - 2, pos :: acc, str)
|
|
||||||
end
|
|
||||||
else if chr = #"\r" then
|
|
||||||
helpCountLineBreaks (pos - 1, pos :: acc, str)
|
|
||||||
else
|
|
||||||
helpCountLineBreaks (pos - 1, acc, str)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
in
|
in
|
||||||
fun countLineBreaks str =
|
fun countLineBreaks str =
|
||||||
helpCountLineBreaks (String.size str - 1, [], str)
|
helpCountLineBreaks (String.size str - 1, [], str)
|
||||||
@@ -49,7 +49,13 @@ struct
|
|||||||
val vecLimit = 32
|
val vecLimit = 32
|
||||||
|
|
||||||
val empty =
|
val empty =
|
||||||
{idx = 0, leftStrings = [], rightStrings = [], line = 0, leftLines = [], rightLines = []}
|
{ idx = 0
|
||||||
|
, leftStrings = []
|
||||||
|
, rightStrings = []
|
||||||
|
, line = 0
|
||||||
|
, leftLines = []
|
||||||
|
, rightLines = []
|
||||||
|
}
|
||||||
|
|
||||||
local
|
local
|
||||||
fun helpToString (acc, input) =
|
fun helpToString (acc, input) =
|
||||||
@@ -71,29 +77,27 @@ struct
|
|||||||
|
|
||||||
local
|
local
|
||||||
fun helpBinSearch (findNum, lines, low, high) =
|
fun helpBinSearch (findNum, lines, low, high) =
|
||||||
if Vector.length lines = 0 then
|
let
|
||||||
0
|
val mid = low + ((high - low) div 2)
|
||||||
else
|
in
|
||||||
let
|
if high >= low then
|
||||||
val mid = low + ((high - low) div 2)
|
let
|
||||||
in
|
val midVal = Vector.sub (lines, mid)
|
||||||
if high >= low then
|
in
|
||||||
let
|
if midVal = findNum then
|
||||||
val midVal = Vector.sub (lines, mid)
|
mid
|
||||||
in
|
else if midVal < findNum then
|
||||||
if midVal = findNum then
|
helpBinSearch (findNum, lines, mid + 1, high)
|
||||||
mid
|
else
|
||||||
else if midVal < findNum then
|
helpBinSearch (findNum, lines, low, mid - 1)
|
||||||
helpBinSearch (findNum, lines, mid + 1, high)
|
end
|
||||||
else
|
else
|
||||||
helpBinSearch (findNum, lines, low, mid - 1)
|
Int.max (0, mid)
|
||||||
end
|
end
|
||||||
else
|
|
||||||
Int.max (0, mid)
|
|
||||||
end
|
|
||||||
in
|
in
|
||||||
fun binSearch (findNum, lines) =
|
fun binSearch (findNum, lines) =
|
||||||
helpBinSearch (findNum, lines, 0, Vector.length lines)
|
if Vector.length lines = 0 then 0
|
||||||
|
else helpBinSearch (findNum, lines, 0, Vector.length lines)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun insWhenIdxAndCurIdxAreEqual
|
fun insWhenIdxAndCurIdxAreEqual
|
||||||
@@ -140,14 +144,14 @@ struct
|
|||||||
let
|
let
|
||||||
val _ = print "line 137\n"
|
val _ = print "line 137\n"
|
||||||
in
|
in
|
||||||
(* Does not fit in limit, so cons instead.*)
|
(* Does not fit in limit, so cons instead.*)
|
||||||
{ idx = curIdx + String.size newString
|
{ idx = curIdx + String.size newString
|
||||||
, line = curLine + Vector.length newLines
|
, line = curLine + Vector.length newLines
|
||||||
, leftStrings = newString :: leftStrings
|
, leftStrings = newString :: leftStrings
|
||||||
, leftLines = newLines :: leftLines
|
, leftLines = newLines :: leftLines
|
||||||
, rightStrings = rightStrings
|
, rightStrings = rightStrings
|
||||||
, rightLines = rightLines
|
, rightLines = rightLines
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
| (_, _) =>
|
| (_, _) =>
|
||||||
(*
|
(*
|
||||||
@@ -156,17 +160,17 @@ struct
|
|||||||
* also means that the other one is empty.
|
* also means that the other one is empty.
|
||||||
* So we don't need to perform addition or consing.
|
* So we don't need to perform addition or consing.
|
||||||
*)
|
*)
|
||||||
let
|
let
|
||||||
val _ = print "line 156\n"
|
val _ = print "line 156\n"
|
||||||
in
|
in
|
||||||
{ idx = String.size newString
|
{ idx = String.size newString
|
||||||
, line = Vector.length newLines
|
, line = Vector.length newLines
|
||||||
, leftStrings = [newString]
|
, leftStrings = [newString]
|
||||||
, leftLines = [newLines]
|
, leftLines = [newLines]
|
||||||
, rightStrings = rightStrings
|
, rightStrings = rightStrings
|
||||||
, rightLines = rightLines
|
, rightLines = rightLines
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
fun insInLeftList
|
fun insInLeftList
|
||||||
( idx
|
( idx
|
||||||
@@ -211,14 +215,17 @@ struct
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
(* Just cons everything; no way we can join while staying in limit. *)
|
(* Just cons everything; no way we can join while staying in limit. *)
|
||||||
let val _ = print "line 210\n" in
|
let
|
||||||
{ idx = curIdx + String.size newString
|
val _ = print "line 210\n"
|
||||||
, line = curLine + Vector.length newLines
|
in
|
||||||
, leftStrings = leftStringsHd :: newString :: leftStringsTl
|
{ idx = curIdx + String.size newString
|
||||||
, leftLines = leftLinesHd :: newLines :: leftLinesTl
|
, line = curLine + Vector.length newLines
|
||||||
, rightStrings = rightStrings
|
, leftStrings = leftStringsHd :: newString :: leftStringsTl
|
||||||
, rightLines = rightLines
|
, leftLines = leftLinesHd :: newLines :: leftLinesTl
|
||||||
} end
|
, rightStrings = rightStrings
|
||||||
|
, rightLines = rightLines
|
||||||
|
}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
(* Need to insert in the middle of the left list. *)
|
(* Need to insert in the middle of the left list. *)
|
||||||
let
|
let
|
||||||
@@ -228,7 +235,8 @@ struct
|
|||||||
val strSub2 = String.substring
|
val strSub2 = String.substring
|
||||||
(leftStringsHd, strLength, String.size leftStringsHd - strLength)
|
(leftStringsHd, strLength, String.size leftStringsHd - strLength)
|
||||||
val midpoint = binSearch (String.size strSub1, leftLinesHd)
|
val midpoint = binSearch (String.size strSub1, leftLinesHd)
|
||||||
val _ = print ("str size:" ^ Int.toString (Vector.length leftLinesHd) ^ "\n")
|
val _ = print
|
||||||
|
("str size:" ^ Int.toString (Vector.length leftLinesHd) ^ "\n")
|
||||||
val _ = print ("midpoint:" ^ Int.toString (midpoint) ^ "\n")
|
val _ = print ("midpoint:" ^ Int.toString (midpoint) ^ "\n")
|
||||||
in
|
in
|
||||||
if
|
if
|
||||||
@@ -236,7 +244,7 @@ struct
|
|||||||
then
|
then
|
||||||
(* Join three strings together. *)
|
(* Join three strings together. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 233\n"
|
val _ = print "line 233\n"
|
||||||
val joinedLines =
|
val joinedLines =
|
||||||
Vector.tabulate
|
Vector.tabulate
|
||||||
( Vector.length leftLinesHd + Vector.length newLines
|
( Vector.length leftLinesHd + Vector.length newLines
|
||||||
@@ -267,15 +275,15 @@ struct
|
|||||||
(* If we can join newString/lines with sub1 while
|
(* If we can join newString/lines with sub1 while
|
||||||
* staying in limit. *)
|
* staying in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 268\n"
|
val _ = print "line 268\n"
|
||||||
val _ = print ("vector length: " ^ Int.toString (Vector.length newLines ) ^ "\n")
|
val _ = print
|
||||||
val _ = print ("midpoint: " ^ Int.toString (
|
("vector length: " ^ Int.toString (Vector.length newLines) ^ "\n")
|
||||||
midpoint) ^ "\n")
|
val _ = print ("midpoint: " ^ Int.toString (midpoint) ^ "\n")
|
||||||
val newLeftLines =
|
val newLeftLines =
|
||||||
Vector.tabulate (midpoint + Vector.length newLines, fn idx =>
|
Vector.tabulate (midpoint + Vector.length newLines, fn idx =>
|
||||||
if idx < midpoint then Vector.sub (leftLinesHd, idx)
|
if idx < midpoint then Vector.sub (leftLinesHd, idx)
|
||||||
else Vector.sub (newLines, idx - midpoint) + String.size strSub1)
|
else Vector.sub (newLines, idx - midpoint) + String.size strSub1)
|
||||||
val _ = print "line 275\n"
|
val _ = print "line 275\n"
|
||||||
val newRightLines = VectorSlice.slice (leftLinesHd, midpoint, SOME
|
val newRightLines = VectorSlice.slice (leftLinesHd, midpoint, SOME
|
||||||
(Vector.length leftLinesHd - midpoint))
|
(Vector.length leftLinesHd - midpoint))
|
||||||
val newRightLines = VectorSlice.vector newRightLines
|
val newRightLines = VectorSlice.vector newRightLines
|
||||||
@@ -299,7 +307,7 @@ struct
|
|||||||
(* If we can join newString/line with sub2 while staying
|
(* If we can join newString/line with sub2 while staying
|
||||||
* in limit. *)
|
* in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 292\n"
|
val _ = print "line 292\n"
|
||||||
val newLeftLines = VectorSlice.slice (leftLinesHd, 0, SOME midpoint)
|
val newLeftLines = VectorSlice.slice (leftLinesHd, 0, SOME midpoint)
|
||||||
val newLeftLines = VectorSlice.vector newLeftLines
|
val newLeftLines = VectorSlice.vector newLeftLines
|
||||||
|
|
||||||
@@ -326,7 +334,7 @@ struct
|
|||||||
else
|
else
|
||||||
(* Can't join on either side while staying in limit. *)
|
(* Can't join on either side while staying in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 319\n"
|
val _ = print "line 319\n"
|
||||||
val lineSub1 = VectorSlice.slice (leftLinesHd, 0, SOME midpoint)
|
val lineSub1 = VectorSlice.slice (leftLinesHd, 0, SOME midpoint)
|
||||||
val lineSub1 = VectorSlice.vector lineSub1
|
val lineSub1 = VectorSlice.vector lineSub1
|
||||||
|
|
||||||
@@ -481,7 +489,7 @@ struct
|
|||||||
if isInLimit (newString, rightStringsHd, newLines, rightLinesHd) then
|
if isInLimit (newString, rightStringsHd, newLines, rightLinesHd) then
|
||||||
(* Allocate new string because we can do so while staying in limit. *)
|
(* Allocate new string because we can do so while staying in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 474\n"
|
val _ = print "line 474\n"
|
||||||
val newRightStringsHd = rightStringsHd ^ newString
|
val newRightStringsHd = rightStringsHd ^ newString
|
||||||
val newRightLinesHd =
|
val newRightLinesHd =
|
||||||
Vector.tabulate
|
Vector.tabulate
|
||||||
@@ -505,14 +513,17 @@ struct
|
|||||||
else
|
else
|
||||||
(* Cons newString and newLines to after-the-head,
|
(* Cons newString and newLines to after-the-head,
|
||||||
* because we can't join while staying in the limit.*)
|
* because we can't join while staying in the limit.*)
|
||||||
let val _ = print "line 498\n" in
|
let
|
||||||
{ idx = curIdx
|
val _ = print "line 498\n"
|
||||||
, line = curLine
|
in
|
||||||
, leftStrings = leftStrings
|
{ idx = curIdx
|
||||||
, leftLines = leftLines
|
, line = curLine
|
||||||
, rightStrings = rightStringsHd :: newString :: rightStringsTl
|
, leftStrings = leftStrings
|
||||||
, rightLines = rightLinesHd :: newLines :: rightLinesTl
|
, leftLines = leftLines
|
||||||
} end
|
, rightStrings = rightStringsHd :: newString :: rightStringsTl
|
||||||
|
, rightLines = rightLinesHd :: newLines :: rightLinesTl
|
||||||
|
}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
(* Have to split rightStringsHd and rightLinesHd in the middle. *)
|
(* Have to split rightStringsHd and rightLinesHd in the middle. *)
|
||||||
let
|
let
|
||||||
@@ -527,7 +538,7 @@ struct
|
|||||||
then
|
then
|
||||||
(* Join three strings together. *)
|
(* Join three strings together. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 520\n"
|
val _ = print "line 520\n"
|
||||||
val newRightStringsHd = String.concat [strSub1, newString, strSub2]
|
val newRightStringsHd = String.concat [strSub1, newString, strSub2]
|
||||||
val newRightLinesHd =
|
val newRightLinesHd =
|
||||||
Vector.tabulate
|
Vector.tabulate
|
||||||
@@ -559,15 +570,12 @@ struct
|
|||||||
* staying in limit. *)
|
* staying in limit. *)
|
||||||
let
|
let
|
||||||
(* strSub1 ^ newString is placed on the left list. *)
|
(* strSub1 ^ newString is placed on the left list. *)
|
||||||
val _ = print "line 552\n"
|
val _ = print "line 552\n"
|
||||||
val newLeftStringsHd = strSub1 ^ newString
|
val newLeftStringsHd = strSub1 ^ newString
|
||||||
val newLeftLinesHd =
|
val newLeftLinesHd =
|
||||||
Vector.tabulate (Vector.length newLines + midpoint, fn idx =>
|
Vector.tabulate (Vector.length newLines + midpoint, fn idx =>
|
||||||
if idx < midpoint then
|
if idx < midpoint then Vector.sub (rightLinesHd, idx)
|
||||||
Vector.sub (rightLinesHd, idx)
|
else Vector.sub (newLines, accessIdx) + String.size strSub1)
|
||||||
else
|
|
||||||
Vector.sub (newLines, accessIdx) + String.size strSub1
|
|
||||||
)
|
|
||||||
|
|
||||||
val _ = print "line 584\n"
|
val _ = print "line 584\n"
|
||||||
val newRightLinesHd =
|
val newRightLinesHd =
|
||||||
@@ -592,7 +600,7 @@ struct
|
|||||||
(* If we can join newString/line with sub2 while staying
|
(* If we can join newString/line with sub2 while staying
|
||||||
* in limit. *)
|
* in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 581\n"
|
val _ = print "line 581\n"
|
||||||
val newRightStringsHd = newString ^ strSub2
|
val newRightStringsHd = newString ^ strSub2
|
||||||
val newRightLinesHd =
|
val newRightLinesHd =
|
||||||
Vector.tabulate
|
Vector.tabulate
|
||||||
@@ -619,7 +627,7 @@ struct
|
|||||||
else
|
else
|
||||||
(* Can't join on either side while staying in limit. *)
|
(* Can't join on either side while staying in limit. *)
|
||||||
let
|
let
|
||||||
val _ = print "line 608\n"
|
val _ = print "line 608\n"
|
||||||
val lineSub1 = VectorSlice.slice (rightLinesHd, 0, SOME midpoint)
|
val lineSub1 = VectorSlice.slice (rightLinesHd, 0, SOME midpoint)
|
||||||
val lineSub1 = VectorSlice.vector lineSub1
|
val lineSub1 = VectorSlice.vector lineSub1
|
||||||
val lineSub2 = VectorSlice.slice (rightLinesHd, midpoint, SOME
|
val lineSub2 = VectorSlice.slice (rightLinesHd, midpoint, SOME
|
||||||
@@ -661,7 +669,7 @@ struct
|
|||||||
(leftStringsHd, rightStringsHd, leftLinesHd, rightLinesHd)
|
(leftStringsHd, rightStringsHd, leftLinesHd, rightLinesHd)
|
||||||
then
|
then
|
||||||
let
|
let
|
||||||
val _ = print "line 650\n"
|
val _ = print "line 650\n"
|
||||||
val nextLine = curLine + Vector.length rightLinesHd
|
val nextLine = curLine + Vector.length rightLinesHd
|
||||||
val newLeftStringsHd = leftStringsHd ^ rightStringsHd
|
val newLeftStringsHd = leftStringsHd ^ rightStringsHd
|
||||||
val newLeftLinesHd =
|
val newLeftLinesHd =
|
||||||
@@ -734,14 +742,17 @@ struct
|
|||||||
end
|
end
|
||||||
| (_, _) =>
|
| (_, _) =>
|
||||||
(* Right string/line is empty. *)
|
(* Right string/line is empty. *)
|
||||||
let val _ = print "line 723\n" in
|
let
|
||||||
{ idx = curIdx
|
val _ = print "line 723\n"
|
||||||
, line = curLine
|
in
|
||||||
, leftStrings = leftStrings
|
{ idx = curIdx
|
||||||
, leftLines = leftLines
|
, line = curLine
|
||||||
, rightStrings = [newString]
|
, leftStrings = leftStrings
|
||||||
, rightLines = [newLines]
|
, leftLines = leftLines
|
||||||
} end
|
, rightStrings = [newString]
|
||||||
|
, rightLines = [newLines]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
fun ins
|
fun ins
|
||||||
( idx
|
( idx
|
||||||
|
|||||||
Reference in New Issue
Block a user