Chris Muller uploaded a new version of Chronology-Core to project The Inbox:
http://source.squeak.org/inbox/Chronology-Core-cmm.52.mcz ==================== Summary ==================== Name: Chronology-Core-cmm.52 Author: cmm Time: 17 December 2019, 6:24:58.728545 pm UUID: 2fcaa724-74e7-46e1-b77e-d976e58e21cf Ancestors: Chronology-Core-mt.51 Ability to run and compare multiple benchmarks at once via: { baselineExpression. altExpression1. altExpression2. "...etc..." } benchCompare The standard bench string is reported for each, along with a percentage rate relative to the baseline, the first one. =============== Diff against Chronology-Core-mt.51 =============== Item was changed: ----- Method: BlockClosure>>benchFor: (in category '*chronology-core') ----- + benchFor: aDuration + "See how many times I can value within the given duration. I'll answer a meaningful description." + ^ self + benchFor: aDuration + do: + [ : metrics | + self + benchMessageForTime: (metrics at: #time) + count: (metrics at: #count) + gc: (metrics at: #gcTime) ]! - benchFor: aDuration - "See how many times I can value within the given duration. I'll answer a meaningful description." - - | startTime shouldRun count elapsedTime roundTo3Digits delay gcStart gcTime | - roundTo3Digits := [:num | - | rounded lowDigit | - rounded := (num * 1000) rounded. "round to 1/1000" - lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" - rounded := rounded roundTo:(10 raisedTo: lowDigit). - (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" - ifTrue: [(rounded // 1000) asStringWithCommas] - ifFalse: [(rounded / 1000.0) printString]]. - delay := aDuration asDelay. - count := 0. - shouldRun := true. - Smalltalk garbageCollect. - [ delay wait. shouldRun := false ] forkAt: Processor timingPriority - 1. - startTime := Time millisecondClockValue. - gcStart := (Smalltalk vmParameterAt: 8) + (Smalltalk vmParameterAt: 10). - [ shouldRun ] whileTrue: [ - self value. - count := count + 1 ]. - elapsedTime := Time millisecondsSince: startTime. - gcTime := (Smalltalk vmParameterAt: 8) + (Smalltalk vmParameterAt: 10) - gcStart. - ^(roundTo3Digits value: count * 1000 / elapsedTime) , ' per second.', (( - #( - (1e-3 'seconds') - (1 'milliseconds') - (1e3 'microseconds') - (1e6 'nanoseconds') - ) - detect: [ :pair | elapsedTime * pair first >= count ] - ifNone: [ #(1e9 'picoseconds') ]) - in: [ :pair | - ' {1} {2} per run.' format: { - (roundTo3Digits value: elapsedTime * pair first / count). - pair second } ]), (' {1} % GC time.' format: {gcTime / elapsedTime * 100 printShowingMaxDecimalPlaces: 5})! Item was added: + ----- Method: BlockClosure>>benchFor:do: (in category '*chronology-core') ----- + benchFor: aDuration do: oneArgBlock + "See how many times I can value within the given duration. I'll answer a meaningful description." + | startTime shouldRun count elapsedTime delay gcStart gcTime | + delay := aDuration asDelay. + count := 0. + shouldRun := true. + Smalltalk garbageCollect. + [ delay wait. shouldRun := false ] forkAt: Processor timingPriority - 1. + startTime := Time millisecondClockValue. + gcStart := (Smalltalk vmParameterAt: 8) + (Smalltalk vmParameterAt: 10). + [ shouldRun ] whileTrue: [ + self value. + count := count + 1 ]. + elapsedTime := Time millisecondsSince: startTime. + gcTime := (Smalltalk vmParameterAt: 8) + (Smalltalk vmParameterAt: 10) - gcStart. + ^ oneArgBlock value: + ({ #time -> elapsedTime. + #count -> count. + #rate -> (count * 1000 / elapsedTime). + #gcTime -> gcTime} as: OrderedDictionary)! Item was added: + ----- Method: BlockClosure>>benchMessageForTime:count:gc: (in category '*chronology-core') ----- + benchMessageForTime: elapsedTime count: count gc: gcTime + | roundTo3Digits | + roundTo3Digits := [:num | + | rounded lowDigit | + rounded := (num * 1000) rounded. "round to 1/1000" + lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" + rounded := rounded roundTo:(10 raisedTo: lowDigit). + (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" + ifTrue: [(rounded // 1000) asStringWithCommas] + ifFalse: [(rounded / 1000.0) printString]]. + ^(roundTo3Digits value: count * 1000 / elapsedTime) , ' per second.', (( + #( + (1e-3 'seconds') + (1 'milliseconds') + (1e3 'microseconds') + (1e6 'nanoseconds') + ) + detect: [ :pair | elapsedTime * pair first >= count ] + ifNone: [ #(1e9 'picoseconds') ]) + in: [ :pair | + ' {1} {2} per run.' format: { + (roundTo3Digits value: elapsedTime * pair first / count). + pair second } ]), (' {1} % GC time.' format: {gcTime / elapsedTime * 100 printShowingMaxDecimalPlaces: 5})! Item was added: + ----- Method: Collection>>benchCompare (in category '*chronology-core') ----- + benchCompare + "Each of my elements is a block to be benched. Bench each and answer a new collection which reports on each element of the receiver relative to the first." + ^ self benchCompareFor: 5 seconds! Item was added: + ----- Method: Collection>>benchCompareFor: (in category '*chronology-core') ----- + benchCompareFor: aDuration + "Each of my elements is a block to be benched. Bench each and answer a new collection which reports on each element of the receiver relative to the first." + ^ self + benchCompareFor: aDuration + do: [ : metrics | self benchMessageFor: metrics ]! Item was added: + ----- Method: Collection>>benchCompareFor:do: (in category '*chronology-core-private') ----- + benchCompareFor: aDuration do: aBlock + "Each of my elements is a block to be benched. Bench each and answer a new collection which reports on each element of the receiver as a fraction of the 'baseline' oscillation performance, an empty block." + | baselineMetrics | + ^ self asArray withIndexCollect: + [ : each : index | each sourceString -> + (each + benchFor: aDuration + do: + [ : metrics | + index = 1 ifTrue: [ baselineMetrics := metrics ]. + { #rate -> #relativeRate. + "any others?" } do: + [ : eachMetric | + metrics + at: eachMetric value + put: (metrics at: eachMetric key) / (baselineMetrics at: eachMetric key) ]. + aBlock value: metrics ]) ]! Item was added: + ----- Method: Collection>>benchMessageFor: (in category '*chronology-core-private') ----- + benchMessageFor: metricsDictionary + "Answer a human-consumable String describing the performance + metrics within metricsDictionary." + ^ String + streamContents: + [ : stream | stream + nextPutAll: + ((metricsDictionary at: #relativeRate) + * 100 printShowingDecimalPlaces: 0) + , '% of baseline rate, ' ; + nextPutAll: + (["responsibility hack, Block knows how to print"] + benchMessageForTime: (metricsDictionary at: #time) + count: (metricsDictionary at: #count) + gc: (metricsDictionary at: #gcTime))]! |
Yay! Finally. ^__^ +1 for after the 5.3 release Best, Marcel
|
Free forum by Nabble | Edit this page |