[ENH] TimeProfileBrowser
Stephen Travis Pope
stp at create.ucsb.edu
Thu Dec 2 20:44:41 UTC 1999
--------------F166D6E78CAE4087C40DEB18
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
The attached file-in is a stand-alone version of the TimeProfileBrowser.
For a description, see http://www.create.ucsb.edu/squeak/STP12.html.
--
stp
Stephen Travis Pope -- http://www.create.ucsb.edu/~stp
stp at expertcity.com -- stp9 at cornell.edu
--------------F166D6E78CAE4087C40DEB18
Content-Type: text/plain; charset=us-ascii;
name="TimeProfileView.2Dece1209pm.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="TimeProfileView.2Dece1209pm.cs"
'From Squeak2.6 of 11 October 1999 [latest update: #1559] on 2 December 1999 at 12:09:36 pm'!
Magnitude subclass: #MessageTally
instanceVariableNames: 'class method tally receivers senders time '
classVariableNames: 'ObservedProcess Timer '
poolDictionaries: ''
category: 'System-Support'!
MessageSet subclass: #TimeProfileBrowser
instanceVariableNames: 'selectedClass selectedSelector block tally '
classVariableNames: 'TextMenu '
poolDictionaries: ''
category: 'Interface-Browser'!
TimeProfileBrowser class
instanceVariableNames: ''!
!MessageTally methodsFor: 'initialize-release' stamp: 'stp 05/07/1999 15:31'!
spyEvery: millisecs on: aBlock
"Create a spy and spy on the given block at the specified rate."
| myDelay value startTime time0 |
(aBlock isMemberOf: BlockContext)
ifFalse: [self error: 'spy needs a block here'].
self class: aBlock receiver class method: aBlock method.
"set up the probe"
ObservedProcess _ Processor activeProcess.
myDelay := Delay forMilliseconds: millisecs.
time0 := Time millisecondClockValue.
Timer :=
[[true] whileTrue:
[startTime := Time millisecondClockValue.
myDelay wait.
self tally: ObservedProcess suspendedContext
"tally can be > 1 if ran a long primitive"
by: (Time millisecondClockValue - startTime) // millisecs].
nil] newProcess.
Timer priority: Processor userInterruptPriority.
"activate the probe and evaluate the block"
Timer resume.
value := aBlock value.
"cancel the probe and return the value"
Timer terminate.
time := Time millisecondClockValue - time0.
^value! !
!MessageTally methodsFor: 'reporting' stamp: 'stp 05/07/1999 14:38'!
report: strm cutoff: threshold
tally = 0
ifTrue: [strm nextPutAll: ' - no tallies obtained']
ifFalse:
[strm nextPutAll: ' - '; print: tally; nextPutAll: ' tallies, ', time printString, ' msec.'; cr; cr.
self fullPrintOn: strm tallyExact: false orThreshold: threshold]! !
!MessageTally methodsFor: 'reporting' stamp: 'stp 05/08/1999 12:06'!
tally
"Answer the receiver's number of tally."
^tally! !
!MessageTally methodsFor: 'reporting' stamp: 'stp 05/08/1999 11:47'!
time
"Answer the receiver's run time."
^time! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
block
"Answer the receiver's 'block'."
^block! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
block: anObject
"Set the receiver's instance variable 'block' to be anObject."
block := anObject! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
selectedClass
"Answer the receiver's 'selectedClass'."
^selectedClass! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
selectedClass: anObject
"Set the receiver's instance variable 'selectedClass' to be anObject."
selectedClass := anObject! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
selectedSelector
"Answer the receiver's 'selectedSelector'."
^selectedSelector! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
selectedSelector: anObject
"Set the receiver's instance variable 'selectedSelector' to be anObject."
selectedSelector := anObject! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
tally
"Answer the receiver's 'tally'."
^tally! !
!TimeProfileBrowser methodsFor: 'accessing' stamp: 'stp 05/08/1999 11:37'!
tally: anObject
"Set the receiver's instance variable 'tally' to be anObject."
tally := anObject! !
!TimeProfileBrowser methodsFor: 'private' stamp: 'stp 05/08/1999 15:36'!
messageListKey: aChar from: view
"Respond to a Command key. Cmd-D means re-run block."
aChar == $d ifTrue: [^ Cursor execute showWhile: [self runBlock]].
^ self arrowKey: aChar from: view! !
!TimeProfileBrowser methodsFor: 'private' stamp: 'stp 05/08/1999 15:27'!
messageListMenu: aMenu shifted: shifted
"Add a menu to the inherited one."
| menu |
menu := super messageListMenu: aMenu shifted: shifted.
" menu addItem: (0)."
^menu! !
!TimeProfileBrowser methodsFor: 'private' stamp: 'stp 05/13/1999 07:02'!
runBlock
| stream list |
tally := MessageTally new.
tally spyEvery: 16 on: block.
stream := ReadWriteStream on: (String new: 2048).
stream nextPutAll: tally tally printString, ' tallies ',
tally time printString, ' msec.'; cr.
tally fullPrintOn: stream tallyExact: false orThreshold: 2.
stream reset.
list := OrderedCollection new.
[stream atEnd]
whileFalse:
[list add: (stream upTo: Character cr). stream next].
self initializeMessageList: list.
self changed: #messageList.
self changed: #messageListIndex.
! !
!TimeProfileBrowser methodsFor: 'private' stamp: 'stp 05/08/1999 15:19'!
selectedMessage
"Answer the source method for the currently selected message."
| source |
self setClassAndSelectorIn: [:class :selector |
source _ class sourceMethodAt: selector ifAbsent: [^ 'Missing'].
Preferences browseWithPrettyPrint ifTrue:
[source _ class compilerClass new
format: source in: class notifying: nil].
^ source asText makeSelectorBoldIn: class].
^''! !
!TimeProfileBrowser methodsFor: 'private' stamp: 'stp 12/2/1999 12:08'!
setClassAndSelectorIn: csBlock
"Decode strings of the form <selectorName> (<className> [class]) "
| string strm class sel parens |
messageListIndex < 3 ifTrue: [^contents := nil]. "Ignore first 2 lines"
string _ self selection asString.
string isEmpty ifTrue: [^contents := nil].
string first == $* ifTrue: [^contents := nil]. "Ignore lines starting with *"
parens := string includes: $(. "Does it have open-paren?"
strm := ReadStream on: string.
parens
ifTrue: [strm skipTo: $(. "easy case"
class := strm upTo: $).
strm next: 2.
sel := strm upToEnd]
ifFalse: [strm position: (string findLast: [ :ch | ch == $ ]).
class := strm upTo: $>.
strm next.
sel := strm upToEnd].
class isEmpty ifTrue: [^contents := nil].
sel isEmpty ifTrue: [^contents := nil].
^MessageSet parse: (class, ' ', sel) toClassAndSelector: csBlock! !
!TimeProfileBrowser class methodsFor: 'instance creation' stamp: 'stp 05/13/1999 07:11'!
onBlock: block
"Open a profile browser on the given block, thereby running the block and
collecting the message tally."
"TimeProfileBrowser onBlock: [20 timesRepeat:
[Transcript show: 100 factorial printString]]"
| inst |
inst := self new.
inst block: block.
inst runBlock.
self open: inst name: 'Time Profile'! !
(StringHolder new textContents:
('
For a demonstration of the TimeProfileBrowser, evaluate the following expression
"TimeProfileBrowser onBlock: [20 timesRepeat:
[Transcript show: 100 factorial printString]]"'))
openLabel: 'TimeProfileBrowser ReadMe'!!
--------------F166D6E78CAE4087C40DEB18--
More information about the Squeak-dev
mailing list
|