[m-rev.] for review: Avoid memory allocation for common string to int conversions.
Peter Wang
novalazy at gmail.com
Mon Jun 20 14:07:55 AEST 2016
It might only be worth doing this for decimal and hexadecimal.
Octal and binary are not really very common.
---
library/string.m:
Make base_string_to_int pass a constant higher order term
to string.foldl_between for common bases 10, 16, 8, 2.
---
library/string.m | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/library/string.m b/library/string.m
index 023ff29..55ef8b3 100644
--- a/library/string.m
+++ b/library/string.m
@@ -5173,12 +5173,12 @@ base_string_to_int(Base, String, Int) :-
End = count_code_units(String),
( if Char = ('-') then
End > 1,
- foldl_between(accumulate_negative_int(Base), String, 1, End, 0, Int)
+ foldl_between(base_negative_accumulator(Base), String, 1, End, 0, Int)
else if Char = ('+') then
End > 1,
- foldl_between(accumulate_int(Base), String, 1, End, 0, Int)
+ foldl_between(base_accumulator(Base), String, 1, End, 0, Int)
else
- foldl_between(accumulate_int(Base), String, 0, End, 0, Int)
+ foldl_between(base_accumulator(Base), String, 0, End, 0, Int)
).
det_base_string_to_int(Base, S) = N :-
@@ -5188,6 +5188,23 @@ det_base_string_to_int(Base, S) = N :-
unexpected($pred, "conversion failed")
).
+:- func base_accumulator(int) = pred(char, int, int).
+:- mode base_accumulator(in) = out(pred(in, in, out) is semidet) is det.
+
+base_accumulator(Base) = Pred :-
+ % Avoid allocating a closure for the common bases.
+ ( if Base = 10 then
+ Pred = accumulate_int(10)
+ else if Base = 16 then
+ Pred = accumulate_int(16)
+ else if Base = 8 then
+ Pred = accumulate_int(8)
+ else if Base = 2 then
+ Pred = accumulate_int(2)
+ else
+ Pred = accumulate_int(Base)
+ ).
+
:- pred accumulate_int(int::in, char::in, int::in, int::out) is semidet.
accumulate_int(Base, Char, N0, N) :-
@@ -5197,6 +5214,24 @@ accumulate_int(Base, Char, N0, N) :-
% XXX depends on undefined behaviour
N0 =< N.
+:- func base_negative_accumulator(int) = pred(char, int, int).
+:- mode base_negative_accumulator(in) = out(pred(in, in, out) is semidet)
+ is det.
+
+base_negative_accumulator(Base) = Pred :-
+ % Avoid allocating a closure for the common bases.
+ ( if Base = 10 then
+ Pred = accumulate_negative_int(10)
+ else if Base = 16 then
+ Pred = accumulate_negative_int(16)
+ else if Base = 8 then
+ Pred = accumulate_negative_int(8)
+ else if Base = 2 then
+ Pred = accumulate_negative_int(2)
+ else
+ Pred = accumulate_negative_int(Base)
+ ).
+
:- pred accumulate_negative_int(int::in, char::in,
int::in, int::out) is semidet.
--
2.6.4
More information about the reviews
mailing list