[squeak-dev] LargeInteger negative bitShift (Rshift) not optimized on byte boundary?

nicolas cellier ncellier at ifrance.com
Tue Jul 1 13:21:09 UTC 2008


I tested this:

| x |
x := SmallInteger maxVal raisedToInteger: 100.
{Time millisecondsToRun: [100000 timesRepeat: [x byteShift: -200]].
 Time millisecondsToRun: [100000 timesRepeat: [x bitShift: -1600]].
 Time millisecondsToRun: [100000 timesRepeat: [x bitShift: -1597]]}.

And got that:
#(95 164 172)

That means that case of exact byte boundary is not optimized for Rshift.

As shown below, it is optimized for LShift:

| x |
x := SmallInteger maxVal raisedToInteger: 100.
{Time millisecondsToRun: [100000 timesRepeat: [x byteShift: 200]].
 Time millisecondsToRun: [100000 timesRepeat: [x bitShift: 1600]].
 Time millisecondsToRun: [100000 timesRepeat: [x bitShift: 1597]]}.
#(103 120 315)

Notice that Rshift seems more efficient than Lshift on non byte boundary (nBits
\\ 8 ~= 0)...

Well, speed factor is not major (<2) but I would expect performance from these
low level primitives...

Ah, the byteShift: code is here if you wanna try:
LargePositiveInteger>>byteShift: n
	"shift by bytes, which is faster than bits when n < 0"
	| shifted |
	n = 0 ifTrue: [^ self].
	n > 0 ifTrue: [
		shifted := self class new: self digitLength + n.
		shifted replaceFrom: n+1 to: self digitLength + n with: self startingAt: 1.
		^ shifted].
	self digitLength + n <= 0 ifTrue: [^0].
	shifted := self class new: self digitLength + n.
	shifted replaceFrom: 1 to: self digitLength + n with: self startingAt: 1 - n.
	^ shifted normalize

Which could also be written:
LargePositiveInteger>>byteShift: n
	"shift by bytes, which is faster than bits when n < 0"
	| shifted |
	n = 0 ifTrue: [^ self].
	self digitLength + n <= 0 ifTrue: [^0].
	shifted := self class new: self digitLength + n.
	shifted replaceFrom: (1 max: 1 + n) to: self digitLength + n with: self
startingAt: (1 max: 1 - n).
	^ shifted normalize




More information about the Squeak-dev mailing list