[Pkg] The Trunk: Kernel-ul.939.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Aug 12 21:25:42 UTC 2015


Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.939.mcz

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

Name: Kernel-ul.939
Author: ul
Time: 12 August 2015, 10:38:42.576 pm
UUID: 6595484c-9c41-45fe-82f3-c689f7ddffa8
Ancestors: Kernel-eem.938

- Magnitude's spaceship operator uses quick returns.
- Number >> #raisedTo: uses #negative and #isZero, which is faster for LargeIntegers than pure comparison with SmallIntegers.
- faster #primesUpTo:do:, and #largePrimesUpTo:do:

=============== Diff against Kernel-eem.938 ===============

Item was changed:
  ----- Method: Integer class>>largePrimesUpTo:do: (in category 'prime numbers') -----
  largePrimesUpTo: max do: aBlock
  	"Evaluate aBlock with all primes up to maxValue.
  	The Algorithm is adapted from http://www.rsok.com/~jrm/printprimes.html
  	It encodes prime numbers much more compactly than #primesUpTo: 
  	38.5 integer per byte (2310 numbers per 60 byte) allow for some fun large primes.
  	(all primes up to SmallInteger maxVal can be computed within ~27MB of memory;
+ 	the regular #primesUpTo: would require one *GIGA*byte).
- 	the regular #primesUpTo: would require 4 *GIGA*bytes).
  	Note: The algorithm could be re-written to produce the first primes (which require
  	the longest time to sieve) faster but only at the cost of clarity."
  
+ 	| n limit flags maskBitIndex bitIndex maskBit byteIndex index primesUpTo2310 indexLimit increments incrementIndex |
- 	| limit flags maskBitIndex bitIndex maskBit byteIndex index primesUpTo2310 indexLimit |
  	limit := max asInteger - 1.
  	indexLimit := max asInteger sqrtFloor + 1.
  	"Create the array of flags."
  	flags := ByteArray new: (limit + 2309) // 2310 * 60 + 60.
  	flags atAllPut: 16rFF. "set all to true"
  
  	"Compute the primes up to 2310"
  	primesUpTo2310 := self primesUpTo: 2310.
  
  	"Create a mapping from 2310 integers to 480 bits (60 byte)"
  	maskBitIndex := Array new: 2310.
  	bitIndex := -1. "for pre-increment"
  	maskBitIndex at: 1 put: (bitIndex := bitIndex + 1).
  	maskBitIndex at: 2 put: (bitIndex := bitIndex + 1).
  
+ 	index := 1.
+ 	[ index <= 5 ] whileTrue: [
+ 		aBlock value: (primesUpTo2310 at: index).
+ 		index := index + 1 ].
+ 	
+ 	n := 2.
+ 	[ n <= 2309 ] whileTrue: [
- 	1 to: 5 do:[:i| aBlock value: (primesUpTo2310 at: i)].
- 
- 	index := 6.
- 	2 to: 2309 do:[:n|
  		[(primesUpTo2310 at: index) < n] 
  			whileTrue:[index := index + 1].
  		n = (primesUpTo2310 at: index) ifTrue:[
  			maskBitIndex at: n+1 put: (bitIndex := bitIndex + 1).
  		] ifFalse:[
  			"if modulo any of the prime factors of 2310, then could not be prime"
  			(n \\ 2 = 0 or:[n \\ 3 = 0 or:[n \\ 5 = 0 or:[n \\ 7 = 0 or:[n \\ 11 = 0]]]]) 
  				ifTrue:[maskBitIndex at: n+1 put: 0]
  				ifFalse:[maskBitIndex at: n+1 put: (bitIndex := bitIndex + 1)].
  		].
+ 		n := n + 1 ].
- 	].
  
  	"Now the real work begins...
  	Start with 13 since multiples of 2,3,5,7,11 are handled by the storage method;
+ 	increment by iterating through increments, which enables us to only check about 20.77% of all numbers."
+ 	n := 13.
+ 	increments := #[4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 6 4 6 8 4 2 4 2 4 14 4 6 2 10 2 6 6 4 2 4 6 2 10 2 4 2 12 10 2 4 2 4 6 2 6 4 6 6 6 2 6 4 2 6 4 6 8 4 2 4 6 8 6 10 2 4 6 2 6 6 4 2 4 6 2 6 4 2 6 10 2 10 2 4 2 4 6 8 4 2 4 12 2 6 4 2 6 4 6 12 2 4 2 4 8 6 4 6 2 4 6 2 6 10 2 4 6 2 6 4 2 4 2 10 2 10 2 4 6 6 2 6 6 4 6 6 2 6 4 2 6 4 6 8 4 2 6 4 8 6 4 6 2 4 6 8 6 4 2 10 2 6 4 2 4 2 10 2 10 2 4 2 4 8 6 4 2 4 6 6 2 6 4 8 4 6 8 4 2 4 2 4 8 6 4 6 6 6 2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10 2 6 4 6 2 6 4 2 4 6 6 8 4 2 6 10 8 4 2 4 2 4 8 10 6 2 4 8 6 6 4 2 4 6 2 6 4 6 2 10 2 10 2 4 2 4 6 2 6 4 2 4 6 6 2 6 6 6 4 6 8 4 2 4 2 4 8 6 4 8 4 6 2 6 6 4 2 4 6 8 4 2 4 2 10 2 10 2 4 2 4 6 2 10 2 4 6 8 6 4 2 6 4 6 8 4 6 2 4 8 6 4 6 2 4 6 2 6 6 4 6 6 2 6 6 4 2 10 2 10 2 4 2 4 6 2 6 4 2 10 6 2 6 4 2 6 4 6 8 4 2 4 2 12 6 4 6 2 4 6 2 12 4 2 4 8 6 4 2 4 2 10 2 10 6 2 4 6 2 6 4 2 4 6 6 2 6 4 2 10 6 8 6 4 2 4 8 6 4 6 2 4 6 2 6 6 6 4 6 2 6 4 2 4 2 10 12 2 4 2 10 2 6 4 2 4 6 6 2 10 2 6 4 14 4 2 4 2 4 8 6 4 6 2 4 6 2 6 6 4 2 4 6 2 6 4 2 4 12 2 12].
+ 	incrementIndex := 1.
+ 	[ n <= limit ] whileTrue: [
- 	increment by 2 for odd numbers only."
- 	13 to: limit by: 2 do:[:n|
  		(maskBit := maskBitIndex at: (n \\ 2310 + 1)) = 0 ifFalse:["not a multiple of 2,3,5,7,11"
  			byteIndex := n // 2310 * 60 + (maskBit-1 bitShift: -3) + 1.
  			bitIndex := 1 bitShift: (maskBit bitAnd: 7).
  			((flags at: byteIndex) bitAnd: bitIndex) = 0 ifFalse:["not marked -- n is prime"
  				aBlock value: n.
  				"Start with n*n since any integer < n has already been sieved 
  				(e.g., any multiple of n with a number k < n has been cleared 
+ 				when k was sieved); add 2 * n to avoid even numbers and
- 				when k was sieved); add 2 * i to avoid even numbers and
  				mark all multiples of this prime. Note: n < indexLimit below
  				limits running into LargeInts -- nothing more."
  				n < indexLimit ifTrue:[
  					index := n * n.
  					[index <= limit] whileTrue:[
  						(maskBit := maskBitIndex at: (index \\ 2310 + 1)) = 0 ifFalse:[
  							byteIndex := (index // 2310 * 60) + (maskBit-1 bitShift: -3) + 1.
  							maskBit := 255 - (1 bitShift: (maskBit bitAnd: 7)).
  							flags at: byteIndex put: ((flags at: byteIndex) bitAnd: maskBit).
  						].
+ 						index := index + n + n ].
- 						index := index + (2 * n)].
  				].
  			].
  		].
+ 		n := n + (increments at: incrementIndex).
+ 		incrementIndex := incrementIndex + 1.
+ 		incrementIndex > increments size ifTrue: [ incrementIndex := 1 ] ]!
- 	].
- !

Item was changed:
  ----- Method: Integer class>>primesUpTo:do: (in category 'prime numbers') -----
  primesUpTo: max do: aBlock
  	"Compute aBlock with all prime integers up to the given integer."
  	"Integer primesUpTo: 100"
  
+ 	| index sieve increment limit limitSqrtFloor |
- 	| index limit limitSqrtFloor sieve increment |
  	limit := max asInteger.
- 	limit <= 1 ifTrue: [ ^self ].
  	"Fall back into #largePrimesUpTo:do: if we'd require more than 100k of memory; 
+ 	the alternative will only requre 2/77th of the amount we need here and is almost as fast."
+ 	limit <= 100000 ifFalse: [ ^self largePrimesUpTo: limit do: aBlock ].
- 	the alternative will only requre 1/154th of the amount we need here and is almost as fast."
- 	limit > 25000 ifTrue:[ ^self largePrimesUpTo: limit do: aBlock ].
  	limit := limit - 1. "upTo:"
+ 	limit <= 1 ifTrue: [ ^self ].
+ 	aBlock value: 2.
+ 	limit <= 2 ifTrue: [ ^self ].
+ 	aBlock value: 3.
+ 	sieve := ByteArray new: limit withAll: 1. "1 = prime, 0 = not prime"
+ 	sieve at: 1 put: 0.
+ 	"Filter multiples of 2."
+ 	index := 4.
+ 	[ index <= limit ] whileTrue: [
+ 		sieve at: index put: 0.
+ 		index := index + 2 ].
+ 	"Filter multiples of 3."
+ 	index := 9.
+ 	[ index <= limit ] whileTrue: [
+ 		sieve at: index put: 0.
+ 		index := index + 3 ].
+ 	"Filter the rest of the primes."
- 	sieve := Array new: limit withAll: true.
- 	sieve at: 1 put: false.
- 	index := 2.
  	limitSqrtFloor := limit sqrtFloor.
+ 	index := 5.
+ 	increment := 2.
- 	increment := 1.
  	[ index <= limitSqrtFloor ] whileTrue: [
+ 		(sieve at: index) = 1 ifTrue: [
+ 			| originalIndex originalIncrement |
- 		(sieve at: index) ifTrue: [
- 			| notPrimeIndex notPrimeIncrement |
  			aBlock value: index.
+ 			originalIndex := index.
+ 			originalIncrement := increment.
+ 			increment := index + index.
+ 			index := index * index.
+ 			[ index <= limit ] whileTrue: [
+ 				sieve at: index put: 0.
+ 				index := index + increment ].
+ 			index := originalIndex.
+ 			increment := originalIncrement ].
- 			notPrimeIndex := index * index.
- 			notPrimeIncrement := increment * index.
- 			[ notPrimeIndex <= limit ] whileTrue: [
- 				sieve at: notPrimeIndex put: false.
- 				notPrimeIndex := notPrimeIndex + notPrimeIncrement ] ].
  		index := index + increment.
+ 		increment := 6 - increment ].
+ 	"No more new primes here."
- 		increment := 2].
  	[ index <= limit ] whileTrue: [
+ 		(sieve at: index) = 1 ifTrue: [
- 		(sieve at: index) ifTrue: [
  			aBlock value: index ].
  		index := index + increment.
+ 		increment := 6 - increment ]!
- 		increment := 2]!

Item was changed:
  ----- Method: Magnitude>><=> (in category 'sorting') -----
  <=> anotherObject
  	"Return a collation order of -1, 0, or 1, indicating whether I should be collated before the receiver, am equal, or after.
  	See also:  http://en.wikipedia.org/wiki/Spaceship_operator"
  
+ 	self = anotherObject ifTrue: [ ^0 ].
+ 	self < anotherObject ifTrue: [ ^-1 ].
+ 	^1!
- 	^self = anotherObject
- 		ifTrue: [0]
- 		ifFalse: [self < anotherObject ifTrue: [-1] ifFalse: [1]]!

Item was changed:
  ----- Method: Number>>raisedTo: (in category 'mathematical functions') -----
  raisedTo: aNumber 
  	"Answer the receiver raised to aNumber."
  
  	aNumber isInteger ifTrue: [
  		"Do the special case of integer power"
  		^ self raisedToInteger: aNumber].
  	aNumber isFraction ifTrue: [
  		"Special case for fraction power"
  		^ (self nthRoot: aNumber denominator) raisedToInteger: aNumber numerator ].
+ 	self negative ifTrue: [
- 	self < 0 ifTrue: [
  		^ ArithmeticError signal: 'Negative numbers can''t be raised to float powers.' ].
+ 	aNumber isZero ifTrue: [^ self class one].	"Special case of exponent=0"
- 	0 = aNumber ifTrue: [^ self class one].	"Special case of exponent=0"
  	1 = aNumber ifTrue: [^ self].	"Special case of exponent=1"
+ 	self isZero ifTrue: [				"Special case of self = 0"
+ 		aNumber negative
- 	0 = self ifTrue: [				"Special case of self = 0"
- 		aNumber < 0
  			ifTrue: [^ (ZeroDivide dividend: self) signal]
  			ifFalse: [^ self]].
  	^ (aNumber * self ln) exp		"Otherwise use logarithms"!



More information about the Packages mailing list