[squeak-dev] The Trunk: Kernel-nice.424.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Mar 14 22:20:00 UTC 2010


Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.424.mcz

==================== Summary ====================

Name: Kernel-nice.424
Author: nice
Time: 14 March 2010, 11:19:27.192 pm
UUID: 0ed744aa-5d6e-470a-9adc-a064c3d874df
Ancestors: Kernel-laza.423

Cache well known digit values in NumberParser for speed.
Testing the base as of previous implementation was not a good idea, because some Unicode characters could have a digitValue < 10.

=============== Diff against Kernel-laza.423 ===============

Item was added:
+ ----- Method: NumberParser classSide>>initializeDigitValues (in category 'class initialization') -----
+ initializeDigitValues
+ 	"Initialize the well known digit value of ascii characters."
+ 	
+ 	DigitValues := Array new: 256 withAll: -1.
+ 	0 to: 255 do: [:i | DigitValues at: i + 1 put: (Character value: i) digitValue]!

Item was added:
+ ----- Method: NumberParser classSide>>initialize (in category 'class initialization') -----
+ initialize
+ 	self initializeDigitValues.!

Item was changed:
  ----- Method: NumberParser>>nextElementaryLargeIntegerBase: (in category 'parsing-large int') -----
  nextElementaryLargeIntegerBase: aRadix
  	"Form an unsigned integer with incoming digits from sourceStream.
  	Return this integer, or zero if no digits found.
  	Stop reading if end of digits or if a LargeInteger is formed.
  	Count the number of digits and the position of lastNonZero digit and store them in instVar"
  
+ 	| value digit code char |
- 	| value digit |
  	value := 0.
  	nDigits := 0.
  	lastNonZero := 0.
+ 	DigitValues ifNil: [self class initializeDigitValues].
+ 	"Avoid using digitValue which is awfully slow"
+ 	[value isLarge or: [(char := sourceStream next) == nil
+ 		or: [code := char charCode.
+ 			digit := code < 256
+ 				ifTrue: [DigitValues at: 1 + code]
+ 				ifFalse: [char digitValue].
+ 			(0 > digit or: [digit >= aRadix])
+ 				and: [sourceStream skip: -1.
+ 					true]]]]
+ 		whileFalse: [
+ 			nDigits := nDigits + 1.
+ 			0 = digit
+ 				ifFalse: [lastNonZero := nDigits].
+ 			value := value * aRadix + digit].
- 	aRadix <= 10
- 		ifTrue: ["Avoid using digitValue which is awfully slow"
- 			[value isLarge or: [sourceStream atEnd
- 				or: [digit := sourceStream next charCode - 48.
- 					(0 > digit
- 							or: [digit >= aRadix])
- 						and: [sourceStream skip: -1.
- 							true]]]]
- 				whileFalse: [nDigits := nDigits + 1.
- 					0 = digit
- 						ifFalse: [lastNonZero := nDigits].
- 					value := value * aRadix + digit]]
- 		ifFalse: [
- 			[value isLarge or: [sourceStream atEnd
- 				or: [digit := sourceStream next digitValue.
- 					(0 > digit
- 							or: [digit >= aRadix])
- 						and: [sourceStream skip: -1.
- 							true]]]]
- 				whileFalse: [nDigits := nDigits + 1.
- 					0 = digit
- 						ifFalse: [lastNonZero := nDigits].
- 					value := value * aRadix + digit]].
  	^value!

Item was changed:
  Object subclass: #NumberParser
  	instanceVariableNames: 'sourceStream base neg integerPart fractionPart exponent scale nDigits lastNonZero requestor failBlock'
+ 	classVariableNames: 'DigitValues'
- 	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Kernel-Numbers'!
  
+ !NumberParser commentStamp: 'nice 3/14/2010 22:42' prior: 0!
- !NumberParser commentStamp: 'nice 2/25/2010 02:34' prior: 0!
  NumberParser is an abstract class for parsing and building numbers from string/stream.
  It offers a framework with utility methods and exception handling.
  
  Number syntax is not defined and should be subclassResponsibility.
  
+ Note that class variable DigitValues is a duplication of Character class variable. This is only an optimization, decoding digitValues being a major contributor of algorithm cost.
+ 
  Instance variables:
  sourceStream <Stream> the stream of characters from which the number is read
  base <Integer> the radix in which to interpret digits
  neg <Boolean> true in case of minus sign
  integerPart <Integer> the integer part of the number
  fractionPart <Integer> the fraction part of the number if any
  exponent <Integer> the exponent used in scientific notation if any
  scale <Integer> the scale used in case of ScaledDecimal number if any
  nDigits <Integer> number of digits read to form an Integer
  lasNonZero <Integer> position of last non zero digit, starting at 1 from left, 0 if all digits are zero
  requestor <TextEditor | nil> can be used to insert an error message in the requestor
  failBlock <BlockClosure> Block to execute whenever an error occurs.
+ 	The fail block can have 0, 1 or 2 arguments (errorString and source position)
+ 	
+ Class variables:
+ DigitValues <Array of: Integer> this is a mapping character asciiCode + 1 -> digit value (or -1 if character is not a digit)!
- 	The fail block can have 0, 1 or 2 arguments (errorString and source position)!




More information about the Squeak-dev mailing list