[Newbies] Re: Efficiently writing to a file

Zulq Alam me at zulq.net
Sun Apr 22 22:37:46 UTC 2007

Hi Ian,

You can get significant improvements by, writing to the file in one go, 
avoiding any intermediate strings, and taking a good guess at the size 
of your buffer.

| bs fs bt ft |
bs := WriteStream on: (String new: 60000).
bt := Time millisecondsToRun:
	[1 to: 10000 do:
		[:i |
		i printOn: bs.
			nextPut: Character cr;
			nextPut: Character lf]].
fs := StandardFileStream fileNamed: 'c:/test4.txt'.
ft := Time millisecondsToRun:
	[[fs nextPutAll: bs contents]
		ensure: [fs close]].
	show: bt asString;
	show: ' / ';
	show: ft asString;
	show: ' / ';
	show: bt + ft asString;

The above runs in about 162ms on my machine where as your initial code 
takes about 275ms.

If, however, I load the VisualWorks implementations of these methods 
(change set attached) the above runs in about 65ms. I wouldn't use this 
change set if I were you - I've probably broken something!

I think number printing could be improved considerably without any 


Ian Oversby wrote:
> Is this a reasonable way of writing to a file?  It seems to run a
> little slower than I would expect.
> Thanks,
> Ian
> | myFile |
> myFile := StandardFileStream fileNamed: 'c:/test.txt'
> Transcript show: (Time millisecondsToRun: [
>    1 to: 10000 do: [
>         :x | myFile nextPutAll: ((x asString) , String crlf)
>     ]]) asString , ' millseconds' ; cr.
> myFile close.

-------------- next part --------------
'From Squeak3.9 of 7 November 2006 [latest update: #7067] on 22 April 2007 at 11:36:08 pm'!

!Integer methodsFor: 'vw' stamp: 'za 4/22/2007 23:06'!
printDigitsOn: aStream base: b 
	"Print a representation of the receiver on the stream, aStream, in
	base b where 2<=b<=256.  The receiver is known to be non-negative."

	self >= b
			[self // b printDigitsOn: aStream base: b].
	aStream nextPut: (Character digitValue: self \\ b)! !

!Integer methodsFor: 'vw' stamp: 'za 4/22/2007 23:06'!
printOn: aStream base: b 
	"Print a representation of the receiver on the stream, aStream, in
	base b where 2<=b<=256."

	b < 2
		ifTrue: [self error: (#errInvalidBase << #dialogs >> 'Invalid base: <1p>'
					expandMacrosWith: b)].
	self < 0
			[aStream nextPut: $-.
			self negated printOn: aStream base: b]
			[self printDigitsOn: aStream base: b]! !

!Integer reorganize!
('arithmetic' * + - / // \\\ alignedTo: crossSumBase: quo:)
('benchmarks' benchFib benchmark tinyBenchmarks)
('bit manipulation' << >> allMask: anyBitOfMagnitudeFrom:to: anyMask: bitAnd: bitClear: bitInvert bitInvert32 bitOr: bitShift: bitShiftMagnitude: bitXor: highBit highBitOfMagnitude lowBit noMask:)
('comparing' < = > hash)
('converting' adaptToComplex:andSend: adaptToFraction:andSend: adaptToScaledDecimal:andSend: asCharacter asColorOfDepth: asComplex asFloat asFloatSimply asFraction asHexDigit asInteger asScaledDecimal: asYear)
('enumerating' timesRepeat:)
('explorer' explorerContents hasContentsInExplorer)
('mathematical functions' factorial gcd: lcm: raisedToInteger:modulo: raisedTo:modulo: take:)
('printing' asStringWithCommas asStringWithCommasSigned asTwoCharacterString asWords destinationBuffer: digitBuffer: isLiteral printOn:base:showRadix: printPaddedWith:to: printPaddedWith:to:base: printStringRadix:)
('printing-numerative' byteEncode:base: printOn:base:length:padded: printStringBase: printStringBase:length:padded: printStringHex printStringLength: printStringLength:padded: printStringPadded: printStringRoman radix: storeOn:base: storeOn:base:length:padded: storeStringBase:length:padded: storeStringHex)
('system primitives' lastDigit replaceFrom:to:with:startingAt:)
('testing' even isInteger isPowerOfTwo isPrime)
('tiles' asPrecedenceName)
('truncation and round off' asLargerPowerOfTwo asPowerOfTwo asSmallerPowerOfTwo atRandom atRandom: ceiling floor normalize rounded truncated)
('private' copyto: digitAdd: digitCompare: digitDiv:neg: digitLogic:op:length: digitLshift: digitMultiply:neg: digitRshift:bytes:lookfirst: digitSubtract: growby: growto: isProbablyPrimeWithK:andQ: print:on:prefix:length:padded: romanDigits:for:on:)
('vw' printDigitsOn:base: printOn:base:)

More information about the Beginners mailing list