Skip to content

Commit

Permalink
Merge branch 'master' into squeaksource
Browse files Browse the repository at this point in the history
  • Loading branch information
LinqLover committed Jun 14, 2023
2 parents 468d3fa + e2a74d8 commit e585007
Show file tree
Hide file tree
Showing 17 changed files with 270 additions and 26 deletions.
99 changes: 93 additions & 6 deletions Environment/Environment.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1282,20 +1282,107 @@ \section{Other interesting tools}
Running the method will result in an exception if the class is not in the environment, as \sq does not know who should receive the message.
This can occur, for example, whenever you use a class that is not part of the base system but stems from a project you installed.
Using the \ind{dependency browser} you can see the dependencies of your package.
You can open the dependency browser through \menu{world main docking bar~\go{} Apps~\go{} Dependency Browser} or from the context menu of a system category in a browser.
You can open the dependency browser through \menu{world main docking bar~\go{} Apps~\go{} Dependency Browser} or from the context menu of a system category in a browser (\menu{browse package~\go{} dependencies}).
\paragraph{Lexicon}
Objects understand all messages for which their class or their superclasses have methods.
The system browser introduced earlier can only show you the methods of one class.
If you want to know all the methods an instance of a class understands you can open the \ind{lexicon}.
You can get the lexicon from the system browser by opening the yellow button menu for the class and selecting \menu{browse protocol (p)}.
\paragraph{Message tally}
\paragraph{Profiling tools}
Sometimes you might write code that is too slow.
The \ind{Message Tally} tool, sometimes also called \ind{profiler}, can help you to determine which parts of your program are slow.
You can start it to record the execution times for all processes in the image from the menu item \menu{world main docking bar~\go{} Extras~\go{} Start Profiler}.
Alternatively, you can also let it observe sections of code by selecting the code, opening the yellow button menu, and choosing \menu{spy on it}.
Note, that the message tally is a sampling profiler, so for detailed information, you will have to let your code run for some seconds (e.g. by running it 1000 times if it only takes little time).
For that, \sq provides a number of profiling tools to measure execution time and help you find bottlenecks.
\index{profiling tools}
\begin{ExecuteSmalltalkScript}
SBEScreenshotRecorder writeTo: './figures/TimeProfile.png' building: [:helper |
| sem window splitter list |
sem := Semaphore new.
[Processor activeProcess environmentAt: ActiveWorldVariable put: helper world. "avoid #useWorldAndHandDuring: to keep stack clean"
[World imageForm] timeProfile.
sem signal] fork.
sem wait.
window := helper foregroundWindow.
helper scaleWindow: window extent: 580 px @ 425 px.
splitter := window allMorphs detect: [:m |
(m isKindOf: ProportionalSplitterMorph) and: [m splitsTopAndBottom]].
splitter repositionBy: 0 px @ 110 px.
helper selectAnyListIn: window at: '##Leaves##' andScrollIntoViewBy: 3.
list := helper listMorphIncludingMatch: '##Leaves##' in: window.
helper
type: '>>frameAndFillRectangle:fillStyle:borderStyle:' into: list;
keyStroke: list key: Character return.
]
\end{ExecuteSmalltalkScript}
\begin{ExecuteSmalltalkScript}
SBEScreenshotRecorder writeTo: './figures/SpaceTally.png' building: [:helper |
(SpaceTally new depth: 2; spaceTally: (PackageInfo named: #Morphic) classes) exploreWithLabel: 'SpaceTally'.
helper scaleWindow: helper foregroundWindow extent: 500 px @ 225 px.
]
\end{ExecuteSmalltalkScript}
First, you can send the message \mthind{BlockClosure}{timeToRun} to a block to measure the time in milliseconds it takes to execute it:
\begin{code}{NB: CANNOT TEST}
[10000 factorial] timeToRun --> 27
\end{code}
\noindent
Alternatively, you can select a piece of code in a workspace, debugger, \autc, open the yellow button menu, and select \menu{tally it}.
If a single execution of the code is too fast to measure (confidently), you can also \emph{benchmark} it by sending \mthind{BlockClosure}{bench} or \mthind{BlockClosure}{benchFor:} to a block.
This will run the block repeatedly and compute a few statistics about the execution time.
\begin{code}{NB: CANNOT TEST}
[10 factorial] bench --> '14,500,000 per second. 68.8 nanoseconds per run. 0 % GC time.'
\end{code}
\index{benchmarks}
\begin{figure}[btp]
\begin{minipage}[t]{0.48\textwidth}
\ifluluelse
{\includegraphics[width=\textwidth]{TimeProfile}}
{\includegraphics[scale=0.7]{TimeProfile}}
\label{fig:TimeProfile}
\end{minipage}
\hfill
\begin{minipage}[t]{0.48\textwidth}
\ifluluelse
{\includegraphics[width=\textwidth]{SpaceTally}}
{\includegraphics[scale=0.7]{exploreWithLabel: 'SpaceTally'}}
\label{fig:SpaceTally}
\end{minipage}
\caption{A time profiler (left) and a space tally (right).}
\end{figure}
If you have discovered that your code is too slow, you might wonder which parts of your code are responsible for the slowness.
For that, \sq provides the \emphind{message tally} tool.
You can start it to record the execution times for your code by selecting the code and choosing \menu{spy on it} from the context menu.
Alternatively, you can let it observe all processes in the image from the menu item \menu{world main docking bar~\go{} Apps~\go{} Message Tally}.
Note that the message tally is a sampling profiler, so for detailed information, you will have to let your code run for some seconds (\eg by running it 1000 times if it only takes a little time).
An extension of the message tally is the \emphind{time profile browser} which allows you to browse the results of a message tally conveniently (see \figref{TimeProfile}).
You can invoke it by sending \mthind{BlockClosure}{timeProfile} to a block.
To get rid of the long stack of the existing process, a practical way to invoke it is:
\begin{code}{NB: CANNOT TEST}
[[10000 factorial] timeProfile] fork
\end{code}
Time is not the only resource that is unfortunately limited.
You can also use the \emphind{space tally} to find out which objects consume the most memory:
\begin{code}{@TEST}
SpaceTally new spaceForInstance: Object new depth: 0. --> 16
SpaceTally new spaceForInstance: Morph new depth: 0. --> 56
SpaceTally new spaceForInstance: Morph new depth: 1. --> 144
SpaceTally new spaceForInstance: Morph new depth: 2. --> 208
\end{code}
\noindent
The \ct{depth} parameter specifies how many levels of the object graph should be traversed.
As you can see, even a plain \ct{Object} instance consumes 16 bytes.
Like the message tally, you can also ask a space tally to analyze all objects in the system by providing a list of classes and exploring the result (see \figref{SpaceTally}):
\begin{code}{NB: CANNOT TEST}
SpaceTally new spaceTally: {TextMorph. Point}.
SpaceTally new depth: 2; spaceTally: (PackageInfo named: #Morphic) classes.
SpaceTally new systemWideSpaceTally.
\end{code}
%=========================================================
\section{Chapter summary}
Expand Down
5 changes: 3 additions & 2 deletions FirstApp/FirstApp.tex
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,9 @@ \section{Organizing methods into protocols}
]
\end{ExecuteSmalltalkScript}
\begin{figure}[htbp]
\includegraphics[width=0.65\textwidth]{Categorize}
\caption{Categorize all uncategorized methods.\label{fig:categorize}}
\centering
\includegraphics[width=0.65\textwidth]{Categorize}
\caption{Categorize all uncategorized methods.\label{fig:categorize}}
\end{figure}

If you have followed along with this example, the third pane may well contain the protocol \protind{as yet unclassified}.
Expand Down
Binary file modified Model/figures/Color-Buttons.pdf
Binary file not shown.
Loading

0 comments on commit e585007

Please sign in to comment.