[squeak-dev] The Trunk: Collections-nice.926.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Mar 3 09:46:03 UTC 2021


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

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

Name: Collections-nice.926
Author: nice
Time: 3 March 2021, 10:46:01.17162 am
UUID: bb5d2ec0-d044-c54f-9e8a-5442626c7573
Ancestors: Collections-nice.925

Fix LimitedPrecisionInterval>>collect: it should avoid accumulating increments which also accumulates rounding errors and make collect: behavior diverge from do:.

Rather than modifying Interval>>collect:, implement the specific inexact arithmetic handling in specific subclass.

Do the same with do: and reverseDo:. This enables restoring the legacy Interval enumerations which perform only one operation per loop instead of two.

Do not check rangeIncludes: in indexOf:startingAt:. This is useless foe exact Interval, and now redundant for LimitedPrecisionInterval thanks to more carefull  implementation of #size.

=============== Diff against Collections-nice.925 ===============

Item was changed:
  ----- Method: Interval>>do: (in category 'enumerating') -----
+ do: aBlock
+ 
+ 	| aValue |
+ 	aValue := start.
+ 	step < 0
+ 		ifTrue: [[stop <= aValue]
+ 				whileTrue: 
+ 					[aBlock value: aValue.
+ 					aValue := aValue + step]]
+ 		ifFalse: [[stop >= aValue]
+ 				whileTrue: 
+ 					[aBlock value: aValue.
+ 					aValue := aValue + step]]!
- do: aBlock 
- 	"Evaluate aBlock for each value of the interval.
- 	Implementation note: instead of repeatedly incrementing the value
- 	    aValue := aValue + step.
- 	until stop is reached,
- 	We prefer to recompute value from start
- 	    aValue := start + (index * step).
- 	This is better for floating points accuracy, while not degrading Integer and Fraction speed too much.
- 	Moreover, this is consistent with methods #at: and #size"
- 	
- 	| aValue index size |
- 	index := 0.
- 	size := self size.
- 	[index < size]
- 		whileTrue: [aValue := start + (index * step).
- 			index := index + 1.
- 			aBlock value: aValue]!

Item was changed:
  ----- Method: Interval>>indexOf:startingAt: (in category 'accessing') -----
  indexOf: anElement startingAt: startIndex
  	"startIndex is an positive integer, the collection index where the search is started."
  
  	| index |
- 	(self rangeIncludes: anElement) ifFalse: [ ^0 ].
  	index := (anElement - start / step) rounded + 1.
  	(index between: startIndex and: self size) ifFalse: [ ^0 ].
  	(self at: index) = anElement ifFalse: [ ^0 ].
  	^index!

Item was changed:
  ----- Method: Interval>>reverseDo: (in category 'enumerating') -----
  reverseDo: aBlock 
+ 	"Evaluate aBlock for each element of my interval, in reverse order."
+ 	| aValue |
+ 	aValue := self last.
+ 	step < 0
+ 		ifTrue: [[start >= aValue]
+ 				whileTrue: [aBlock value: aValue.
+ 					aValue := aValue - step]]
+ 		ifFalse: [[start <= aValue]
+ 				whileTrue: [aBlock value: aValue.
+ 					aValue := aValue - step]]!
- 	"Evaluate aBlock for each element of my interval, in reverse order.
- 	Implementation notes: see do: for an explanation on loop detail"
- 
- 	| aValue index |
- 	index := self size.
- 	[index > 0]
- 		whileTrue: [
- 			index := index - 1.
- 			aValue := start + (index * step).
- 			aBlock value: aValue]!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>collect: (in category 'enumerating') -----
+ collect: aBlock
+ 	"Evaluate aBlock with each of the receiver's elements as the argument.  
+ 	Collect the resulting values into a collection like the receiver. Answer  
+ 	the new collection.
+ 	Implementation notes: see do: for an explanation on loop detail"
+ 	| result |
+ 	result := self species new: self size.
+ 	1 to: result size do:
+ 		[:i |
+ 		"(self at: i) is inlined here to avoid repeated bound checking"
+ 		result at: i put: i - 1 * step + start].
+ 	^ result!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>do: (in category 'enumerating') -----
+ do: aBlock 
+ 	"Evaluate aBlock for each value of the interval.
+ 	Implementation note: instead of repeatedly incrementing the value
+ 	    aValue := aValue + step.
+ 	until stop is reached,
+ 	We prefer to recompute value from start
+ 	    aValue := start + (index * step).
+ 	This is better for floating points accuracy, while not degrading Integer and Fraction speed too much.
+ 	Moreover, this is consistent with methods #at: and #size"
+ 	
+ 	| aValue index size |
+ 	index := 0.
+ 	size := self size.
+ 	[index < size]
+ 		whileTrue: [aValue := start + (index * step).
+ 			index := index + 1.
+ 			aBlock value: aValue]!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>reverseDo: (in category 'enumerating') -----
+ reverseDo: aBlock 
+ 	"Evaluate aBlock for each element of my interval, in reverse order.
+ 	Implementation notes: see do: for an explanation on loop detail"
+ 
+ 	| aValue index |
+ 	index := self size.
+ 	[index > 0]
+ 		whileTrue: [
+ 			index := index - 1.
+ 			aValue := start + (index * step).
+ 			aBlock value: aValue]!



More information about the Squeak-dev mailing list