<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
Hi Chris --<div><br></div><div>Please make sure to have Text >> #format: be on par with your changes.</div><div><br></div><div>Note that you changes put more pressure on the GC:</div><div><br></div><div><div><span style="font-size: 13.3333px">['Hello {1}!' format: { 'Squeak' }] bench</span></div><div><span style="font-size: 13.3333px"><br></span></div><div><span style="font-size: 13.3333px">BEFORE: '2,320,000 per second. 432 nanoseconds per run. 1.63967 % GC time.' </span></div><div><span style="font-size: 13.3333px">AFTER: '1,340,000 per second. 746 nanoseconds per run. 16.92 % GC time.' </span></div></div><div><br></div><div>Maybe we can tweak it a little bit more.</div><div><br></div><div><span style="font-size: 10pt">Best,</span><br></div><div>Marcel</div><div><br></div><div>P.S.: <span style="font-size: 10pt">If you had not opted for re-layouting the entire method, I would be able to actually see what you changed there... ;-) ... pretty-print for obfuscation, I suppose? :-D</span></div><div class="mb_sig"></div>
<blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
<p style="color: #AAAAAA; margin-top: 10px;">Am 07.07.2022 06:22:28 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">Chris Muller uploaded a new version of Collections to project The Trunk:<br>http://source.squeak.org/trunk/Collections-cmm.1016.mcz<br><br>==================== Summary ====================<br><br>Name: Collections-cmm.1016<br>Author: cmm<br>Time: 6 July 2022, 11:22:16.540715 pm<br>UUID: 8eaa5fee-446e-4ccb-ae26-652e7a70e693<br>Ancestors: Collections-eem.1015<br><br>Let String>>#format: also support alphanumeric tokens (accessed via a Dictionary). Backward compatibility with classic numeric tokens via a SequenceableCollection is preserved.<br><br>=============== Diff against Collections-eem.1015 ===============<br><br>Item was changed:<br> ----- Method: String>>format: (in category 'formatting') -----<br>+ format: aCollection <br>+ "Substitute tokens in the receiver with element values of aCollection. The tokens are indicated in curly-braces and may be either numeric, e.g., {1}, {2}, etc. and map to a SequenceableCollection, OR, alphanumeric, e.g., {name}, {date}, etc., in which case aCollection should be a Dictionary.<br>+ The values can be static or, with the specification of a Block element, dynamic.<br>+ <br>+ Simplest examples:<br>+ 'foo {date} bar' format: ({'date'->Date today} as: Dictionary).<br>+ <br>+ Dynamic calculation is allowed via Blocks.<br>+ 'foo {NOW} bar' format: ({'NOW'-> [DateAndTime now]} as: Dictionary).<br>+ <br>+ Backward-compatible with numeric-only #format:<br>- format: arguments <br>- "Format the receiver with arguments.<br>- <br>- Simplest example:<br> 'foo {1} bar' format: {Date today}.<br>+ <br>+ Now with block support:<br>+ 'foo {1} bar' format: {[Date today]}.<br>+ <br>+ Complete example with escaped characters: <br>- <br>- Complete example:<br> '\{ \} \\ foo {1} bar {2}' format: {12. 'string'}.<br>+ '\{ \} \\ foo {FOO} bar {BAR}' format: ({'FOO'->12. 'BAR'->'string'} as: Dictionary).<br> "<br>+ ^ self class new: self size * 11 // 10 "ready for +10% growth"streamContents:<br>+ [ : output | | lastIndex nextIndex key |<br>+ lastIndex := 1.<br>+ key := WriteStream on: (String new: 10).<br>+ [ "stream to output until first { or \"<br>+ (nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse:<br>+ [ nextIndex = lastIndex ifFalse:<br>+ [ output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ].<br>+ "special char hit, escape char?"<br>+ (self at: nextIndex) == $\<br>+ ifTrue: [ "transfer the escaped character."<br>+ output nextPut: (self at: (nextIndex := nextIndex + 1)) ]<br>+ ifFalse:<br>+ [ | nextKeyChar |<br>+ "${ char, parse the key"<br>+ [ nextKeyChar := self at: (nextIndex := nextIndex + 1).<br>+ nextKeyChar isAlphaNumeric ] whileTrue: [ key nextPut: nextKeyChar ].<br>+ nextKeyChar = $} ifFalse: [ self error: '$} expected' ].<br>+ output nextPutAll: (aCollection at: key contents numberOrValue) value asString.<br>+ key reset ].<br>+ lastIndex := nextIndex + 1 ].<br>+ lastIndex <= self size ifTrue:<br>+ [ output<br>+ next: self size - lastIndex + 1<br>+ putAll: self<br>+ startingAt: lastIndex ] ]!<br>- ^ self class new: self size * 11 // 10 "+10%" streamContents: [ :output |<br>- | lastIndex nextIndex |<br>- lastIndex := 1.<br>- [ (nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse: [<br>- nextIndex = lastIndex ifFalse: [<br>- output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ].<br>- (self at: nextIndex) caseOf: {<br>- [ $\ ] -> [ output nextPut: (self at: (nextIndex := nextIndex + 1)) ].<br>- [ ${ ] -> [<br>- "Parse the index - a positive integer in base 10."<br>- | digitValue collectionIndex |<br>- collectionIndex := 0.<br>- [ (digitValue := self basicAt: (nextIndex := nextIndex + 1)) between: 48 "$0 asciiValue" and: 57 "$9 asciiValue" ] whileTrue: [<br>- collectionIndex := collectionIndex * 10 + digitValue - 48 "$0 asciiValue". ].<br>- digitValue = 125 "$} asciiValue" ifFalse: [ self error: ('{1} expected' translated format: {$}}) ].<br>- output nextPutAll: (arguments at: collectionIndex) asString ] }.<br>- lastIndex := nextIndex + 1 ].<br>- lastIndex <= self size ifTrue: [<br>- output next: self size - lastIndex + 1 putAll: self startingAt: lastIndex ] ]!<br><br><br></div></blockquote></div>