life if-statement up (so that the test is only done once, to help the branch predictor)

This commit is contained in:
2024-07-04 03:24:34 +01:00
parent b70763b7b8
commit c6fef0499e
3 changed files with 90 additions and 77 deletions

BIN
bench/line_gap_svelte Executable file

Binary file not shown.

BIN
bench/line_rope_svelte Executable file

Binary file not shown.

View File

@@ -41,7 +41,6 @@ struct
, rightLines: int vector list , rightLines: int vector list
} }
val stringLimit = 1024 val stringLimit = 1024
val vecLimit = 32 val vecLimit = 32
@@ -268,45 +267,53 @@ struct
then then
(* 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 if midpoint >= 0 then
val newLeftLines = (* Implicit: a binSearch match was found. *)
if midpoint >= 0 then let
(* Implicit: a binSearch match was found. *) val newLeftLinesLength = midpoint + 1 + Vector.length newLines
let val newLeftLines = Vector.tabulate (newLeftLinesLength, fn idx =>
val newLeftLinesLength = midpoint + 1 + Vector.length newLines if idx <= midpoint then
in Vector.sub (leftLinesHd, idx)
Vector.tabulate (newLeftLinesLength, fn idx => else
if idx <= midpoint then Vector.sub (newLines, idx - (midpoint + 1))
Vector.sub (leftLinesHd, idx) + String.size strSub1)
else
Vector.sub (newLines, idx - (midpoint + 1))
+ String.size strSub1)
end
else
Vector.map (fn el => el + String.size strSub1) newLines
val newRightLines = val newRightLines =
if midpoint >= 0 then
(* Implicit: a binSearch match was found. *)
Vector.tabulate Vector.tabulate
( (Vector.length leftLinesHd - midpoint) - 1 ( (Vector.length leftLinesHd - midpoint) - 1
, fn idx => , fn idx =>
Vector.sub (leftLinesHd, idx + midpoint + 1) Vector.sub (leftLinesHd, idx + midpoint + 1)
- String.size strSub1 - String.size strSub1
) )
else in
{ idx = prevIdx + String.size strSub1 + String.size newString
, line =
(curLine - Vector.length leftLinesHd)
+ Vector.length newLeftLines
, leftStrings = (strSub1 ^ newString) :: leftStringsTl
, leftLines = newLeftLines :: leftLinesTl
, rightStrings = strSub2 :: rightStrings
, rightLines = newRightLines :: rightLines
}
end
else
let
(* No binSearch result found. *)
val newLeftLines =
Vector.map (fn el => el + String.size strSub1) newLines
val newRightLines =
Vector.map (fn idx => idx - String.size strSub1) leftLinesHd Vector.map (fn idx => idx - String.size strSub1) leftLinesHd
in in
{ idx = prevIdx + String.size strSub1 + String.size newString { idx = prevIdx + String.size strSub1 + String.size newString
, line = , line =
(curLine - Vector.length leftLinesHd) (curLine - Vector.length leftLinesHd)
+ Vector.length newLeftLines + Vector.length newLeftLines
, leftStrings = (strSub1 ^ newString) :: leftStringsTl , leftStrings = (strSub1 ^ newString) :: leftStringsTl
, leftLines = newLeftLines :: leftLinesTl , leftLines = newLeftLines :: leftLinesTl
, rightStrings = strSub2 :: rightStrings , rightStrings = strSub2 :: rightStrings
, rightLines = newRightLines :: rightLines , rightLines = newRightLines :: rightLines
} }
end end
else if else if
String.size newString + String.size strSub2 <= stringLimit String.size newString + String.size strSub2 <= stringLimit
andalso andalso
@@ -594,50 +601,57 @@ struct
then then
(* 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 if midpoint >= 0 then
(* strSub1 ^ newString is placed on the left list. *) let
val newLeftStringsHd = strSub1 ^ newString (* Implicit: a binSearch match was found. *)
val newLeftLinesHd = val newLeftStringsHd = strSub1 ^ newString
if midpoint >= 0 then val newLeftLinesLength = midpoint + 1 + Vector.length newLines
(* Implicit: a binSearch match was found. *) val newLeftLinesHd =
let Vector.tabulate (newLeftLinesLength, fn idx =>
val newLeftLinesLength = midpoint + 1 + Vector.length newLines if idx <= midpoint then
in Vector.sub (rightLinesHd, idx)
Vector.tabulate (newLeftLinesLength, fn idx => else
if idx <= midpoint then Vector.sub (newLines, idx - (midpoint + 1))
Vector.sub (rightLinesHd, idx) + String.size strSub1)
else
Vector.sub (newLines, idx - (midpoint + 1))
+ String.size strSub1)
end
else
Vector.map (fn el => el + String.size strSub1) newLines
val newRightLinesHd = val newRightLinesHd =
if midpoint >= 0 then
(* Implicit: a binSearch match was found. *)
Vector.tabulate Vector.tabulate
( (Vector.length rightLinesHd - midpoint) - 1 ( (Vector.length rightLinesHd - midpoint) - 1
, fn idx => , fn idx =>
Vector.sub (rightLinesHd, idx + midpoint + 1) Vector.sub (rightLinesHd, idx + midpoint + 1)
- String.size strSub1 - String.size strSub1
) )
else in
{ idx = curIdx + String.size newLeftStringsHd
, line = curLine + Vector.length newLeftLinesHd
, leftStrings = newLeftStringsHd :: leftStrings
, leftLines = newLeftLinesHd :: leftLines
, rightStrings = strSub2 :: rightStringsTl
, rightLines = newRightLinesHd :: rightLinesTl
}
end
else
let
(* No binSearch match found. *)
val newLeftStringsHd = strSub1 ^ newString
val newLeftLinesHd =
Vector.map (fn el => el + String.size strSub1) newLines
val newRightLinesHd =
Vector.map (fn idx => idx - String.size strSub1) rightLinesHd Vector.map (fn idx => idx - String.size strSub1) rightLinesHd
in in
{ idx = curIdx + String.size newLeftStringsHd { idx = curIdx + String.size newLeftStringsHd
, line = curLine + Vector.length newLeftLinesHd , line = curLine + Vector.length newLeftLinesHd
, leftStrings = newLeftStringsHd :: leftStrings , leftStrings = newLeftStringsHd :: leftStrings
, leftLines = newLeftLinesHd :: leftLines , leftLines = newLeftLinesHd :: leftLines
, rightStrings = strSub2 :: rightStringsTl , rightStrings = strSub2 :: rightStringsTl
, rightLines = newRightLinesHd :: rightLinesTl , rightLines = newRightLinesHd :: rightLinesTl
} }
end end
else if else if
String.size newString + String.size strSub2 <= stringLimit String.size newString + String.size strSub2 <= stringLimit
andalso andalso
(Vector.length rightLinesHd - midpoint) + Vector.length newLines (Vector.length rightLinesHd - midpoint) + Vector.length newLines
<= vecLimit <= vecLimit
then then
(* If we can join newString/line with sub2 while staying (* If we can join newString/line with sub2 while staying
* in limit. *) * in limit. *)
@@ -668,7 +682,6 @@ struct
+ Vector.length newLeftLinesHd + Vector.length newLeftLinesHd
) - String.size strSub1) + String.size newString ) - String.size strSub1) + String.size newString
) )
in in
{ idx = curIdx + String.size strSub1 { idx = curIdx + String.size strSub1
, line = curLine + Vector.length newLeftLinesHd , line = curLine + Vector.length newLeftLinesHd
@@ -729,8 +742,8 @@ struct
(case (leftStrings, leftLines) of (case (leftStrings, leftLines) of
(leftStringsHd :: leftStringsTl, leftLinesHd :: leftLinesTl) => (leftStringsHd :: leftStringsTl, leftLinesHd :: leftLinesTl) =>
if if
isInLimit isInLimit
(leftStringsHd, rightStringsHd, leftLinesHd, rightLinesHd) (leftStringsHd, rightStringsHd, leftLinesHd, rightLinesHd)
then then
let let
val nextLine = curLine + Vector.length rightLinesHd val nextLine = curLine + Vector.length rightLinesHd
@@ -805,13 +818,13 @@ struct
end end
| (_, _) => | (_, _) =>
(* Right string/line is empty. *) (* Right string/line is empty. *)
{ idx = curIdx { idx = curIdx
, line = curLine , line = curLine
, leftStrings = leftStrings , leftStrings = leftStrings
, leftLines = leftLines , leftLines = leftLines
, rightStrings = [newString] , rightStrings = [newString]
, rightLines = [newLines] , rightLines = [newLines]
} }
fun ins fun ins
( idx ( idx