--- a/Number.st Sun Jul 21 19:13:44 2019 +0200
+++ b/Number.st Sun Jul 21 21:09:05 2019 +0200
@@ -114,6 +114,44 @@
"
!
+fastFromString:aString at:startIndex
+ "return the next Float, Integer or ShortFloat from the string.
+ No spaces are skipped.
+
+ This is a specially tuned entry (using a low-level C-call), which
+ returns garbage if the argument string is not a valid float number.
+ It has been added to allow high speed string decomposition into numbers,
+ especially for mass-data."
+
+ self subclassResponsibility
+
+ "
+ Float fromString:'12345.0'
+ Float fastFromString:'12345.0'
+
+ Integer fromString:'12345'
+ Integer fastFromString:'12345'
+
+ should be roughly 10times faster than the general method:
+
+ Time millisecondsToRun:[
+ 100000 timesRepeat:[ Float fromString:'12345.0' ]
+ ].
+ Time millisecondsToRun:[
+ 100000 timesRepeat:[ Float fastFromString:'12345.0' ]
+ ].
+
+ Time millisecondsToRun:[
+ 100000 timesRepeat:[ Integer fromString:'12345' ]
+ ].
+ Time millisecondsToRun:[
+ 100000 timesRepeat:[ Integer fastFromString:'12345' ]
+ ].
+ "
+
+ "Created: / 21-07-2019 / 19:17:17 / Claus Gittinger"
+!
+
fromNumber:aNumber
"return aNumber coerced to myself"
@@ -520,7 +558,7 @@
^ [
|value intValue mantissaAndScale scale decimalMantissa str
- nextChar radix sign signExp exp numerator denom expChar fragment|
+ nextChar radix sign signExp exp numerator denom expChar fragment mantissa|
str := aStringOrStream readStream.
@@ -529,13 +567,11 @@
(nextChar == $-) ifTrue:[
sign := -1.
- str next.
- nextChar := str peekOrNil
+ nextChar := str nextPeekOrNil
] ifFalse:[
sign := 1.
(nextChar == $+) ifTrue:[
- str next.
- nextChar := str peekOrNil
+ nextChar := str nextPeekOrNil
]
].
nextChar == $( ifTrue:[
@@ -576,27 +612,16 @@
intValue := 0.
] ifFalse:[
(allowCStyle and:[nextChar == $0]) ifTrue:[
- str next.
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
nextChar isNil ifTrue:[^ 0].
- nextChar == $x ifTrue:[
- str next.
- radix := 16.
- ] ifFalse:[
- nextChar == $b ifTrue:[
- str next.
- radix := 2.
- ] ifFalse:[
- nextChar == $o ifTrue:[
- str next.
- radix := 8.
- ] ifFalse:[
- nextChar isDigit ifFalse:[
- ^ 0
- ].
- ].
- ].
- ].
+ nextChar == $x ifTrue:[ str next. radix := 16 ]
+ ifFalse:[ nextChar == $b ifTrue:[ str next. radix := 2 ]
+ ifFalse:[ nextChar == $o ifTrue:[ str next. radix := 8 ]
+ ifFalse:[
+ nextChar isDigit ifFalse:[
+ ^ 0
+ ].
+ ]]].
value := Integer readFrom:str radix:radix.
nextChar := str peekOrNil.
] ifFalse:[
@@ -608,7 +633,7 @@
(fragment conform:#isDigit) ifFalse:[
^ exceptionBlock value.
].
- value := (value * 1000) + (Integer readFrom:fragment).
+ value := (value * 1000) + (Integer fastFromString:fragment at:1).
nextChar := str peekOrNil.
].
((nextChar == $r) or:[ nextChar == $R]) ifTrue:[
@@ -625,11 +650,9 @@
(self == Integer or:[self inheritsFrom:Integer]) ifFalse:[
(decimalPointCharacters includes:nextChar) ifTrue:[
- str next.
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
decimalMantissa := 0.
(nextChar notNil and:[nextChar isDigitRadix:radix]) ifTrue:[
- |mantissa|
mantissaAndScale := self readMantissaAndScaleFrom:str radix:radix.
mantissa := mantissaAndScale first.
value := (mantissa coerce:value) + mantissa.
@@ -639,18 +662,14 @@
('eEdDqQfF' includes:nextChar) ifTrue:[
expChar := nextChar.
- str next.
-
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
signExp := 1.
(nextChar == $+) ifTrue:[
- str next.
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
] ifFalse:[
(nextChar == $-) ifTrue:[
- str next.
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
signExp := -1
]
].
@@ -689,9 +708,7 @@
]
] ifFalse:[
('sS' includes:nextChar) ifTrue:[
- str next.
-
- nextChar := str peekOrNil.
+ nextChar := str nextPeekOrNil.
(nextChar notNil and:[ nextChar isDigit]) ifTrue:[
scale := (Integer readFrom:str).
].
@@ -788,7 +805,7 @@
"
"Created: / 21-07-2019 / 13:05:04 / Claus Gittinger"
- "Modified (format): / 21-07-2019 / 17:58:37 / Claus Gittinger"
+ "Modified: / 21-07-2019 / 19:40:34 / Claus Gittinger"
!
readFrom:aStringOrStream decimalPointCharacters:decimalPointCharacters thousandsSeparator:thousandsSeparator onError:exceptionBlock