[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.
bs
nextPut: Character cr;
nextPut: Character lf]].
fs := StandardFileStream fileNamed: 'c:/test4.txt'.
ft := Time millisecondsToRun:
[[fs nextPutAll: bs contents]
ensure: [fs close]].
Transcript
show: bt asString;
show: ' / ';
show: ft asString;
show: ' / ';
show: bt + ft asString;
cr.
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
primitives.
Thanks,
Zulq.
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
ifTrue:
[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
ifTrue:
[aStream nextPut: $-.
self negated printOn: aStream base: b]
ifFalse:
[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