Hello Ben with your help and some more digging around I managed to solve my issues and I am now also able to update the taskbar button moprh without any major hit to my cpu. Pharo is now at 6-7% of one core which is not bad at all.
So what you mention does not seem to affect my performance. However there is still the problem of ChronoManager taking over a second to open its gui . The problem with the loading of image is purely on how PNG are loaded. For example if I profile ChronosManager open I get 1241 for my the initialisation of the class out of this 800ms are wasted just loading the pngs with this summary 48.8% {794ms} Form class>>fromFileNamed: | 47.9% {779ms} Form class>>fromBinaryStream: | 47.9% {779ms} ImageReadWriter class>>formFromStream: | 47.9% {779ms} PNGReadWriter>>nextImage | 47.6% {774ms} PNGReadWriter>>processIDATChunk | 47.2% {768ms} PNGReadWriter>>processNonInterlaced | 32.9% {536ms} PNGReadWriter>>filterScanline:count: | |28.0% {456ms} PNGReadWriter>>filterPaeth: | | |15.4% {250ms} PNGReadWriter>>paethPredictLeft:above:aboveLeft: | | |12.6% {205ms} primitives Reading the full report is clear that a major hit is how pharo tries to compile the png to a form. full report 1624 tallies, 1626 msec. **Tree** -------------------------------- Process: other processes -------------------------------- 15.1% {246ms} InputEventFetcher>>eventLoop 15.1% {246ms} InputEventFetcher>>waitForInput 8.6% {139ms} SoundPlayer class>>playLoop 8.3% {134ms} primitives -------------------------------- Process: (40s) Morphic UI Process: nil -------------------------------- 76.3% {1241ms} ChronosManager class(Behavior)>>new 76.3% {1241ms} ChronosManager>>initialize 76.3% {1241ms} ChrGUIMorph class(Behavior)>>new 76.3% {1241ms} ChrGUIMorph>>initialize 48.8% {794ms} ChrGUIMorph>>secondsTimerForm |48.8% {794ms} Form class>>fromFileNamed: | 47.9% {779ms} Form class>>fromBinaryStream: | 47.9% {779ms} ImageReadWriter class>>formFromStream: | 47.9% {779ms} PNGReadWriter>>nextImage | 47.6% {774ms} PNGReadWriter>>processIDATChunk | 47.2% {768ms} PNGReadWriter>>processNonInterlaced | 32.9% {536ms} PNGReadWriter>>filterScanline:count: | |28.0% {456ms} PNGReadWriter>>filterPaeth: | | |15.4% {250ms} PNGReadWriter>>paethPredictLeft:above:aboveLeft: | | |12.6% {205ms} primitives | |2.8% {46ms} PNGReadWriter>>filterHorizontal: | |1.6% {26ms} PNGReadWriter>>filterVertical: | 7.0% {113ms} ZLibReadStream(InflateStream)>>next:into:startingAt: | |7.0% {113ms} ZLibReadStream(InflateStream)>>next | | 7.0% {113ms} ZLibReadStream(InflateStream)>>pastEndRead | | 4.7% {76ms} ZLibReadStream(InflateStream)>>next | | 1.9% {31ms} ZLibReadStream(InflateStream)>>bitPosition | 3.0% {49ms} primitives | 2.6% {43ms} ZLibReadStream(InflateStream)>>next | |2.6% {43ms} ZLibReadStream(InflateStream)>>pastEndRead | | 1.7% {28ms} ZLibReadStream(InflateStream)>>next | 1.2% {19ms} PNGReadWriter>>copyPixelsRGBA: 21.1% {342ms} ChrStopwatchPanelM class(Behavior)>>new |21.1% {342ms} ChrStopwatchPanelM>>initialize | 3.0% {48ms} ChrStopwatchSettingsPNG>>stopwatchSecondaryPanelIcon | |2.3% {37ms} Form class>>fromBinaryStream: | | 2.3% {37ms} ImageReadWriter class>>formFromStream: | | 2.3% {37ms} PNGReadWriter>>nextImage | | 2.3% {37ms} PNGReadWriter>>processIDATChunk | | 2.3% {37ms} PNGReadWriter>>processNonInterlaced | | 2.0% {33ms} PNGReadWriter>>filterScanline:count: | | 1.9% {31ms} PNGReadWriter>>filterPaeth: | | 1.1% {18ms} primitives | 2.8% {46ms} ChrStopwatchPanelM>>prepareStopwatchButton | |2.7% {44ms} ChrSwitchButtonM class>>createWithAction: | | 2.7% {44ms} ChrSwitchButtonM class(Behavior)>>new | | 2.7% {44ms} ChrSwitchButtonM>>initialize | | 2.6% {42ms} ChronosManager class>>defaultFont | | 2.6% {42ms} ChronosManager class>>defaultFontPointSize: | | 2.3% {38ms} FileReference(AbstractFileReference)>>allDirectories | | 2.3% {38ms} SelectVisitor class>>breadthFirst:select: | | 2.3% {38ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.3% {38ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.3% {38ms} BreadthFirstGuide>>show: | | 2.3% {38ms} BreadthFirstGuide>>visitNextEntry: | | 2.3% {38ms} FileReference>>entries | | 2.3% {38ms} FileSystem>>entriesAt: | | 2.3% {38ms} FileSystem>>entriesAt:do: | | 2.3% {38ms} FileSystem>>entriesAt:ifAbsent:do: | | 2.0% {33ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 1.8% {29ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | | 1.6% {26ms} primitives | 2.8% {45ms} ChrStopwatchPanelM>>prepareHelpLabel | |2.8% {45ms} ChronosManager class>>defaultFontPointSize: | | 2.3% {38ms} FileReference(AbstractFileReference)>>allDirectories | | 2.3% {38ms} SelectVisitor class>>breadthFirst:select: | | 2.3% {38ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.3% {38ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.3% {38ms} BreadthFirstGuide>>show: | | 2.3% {38ms} BreadthFirstGuide>>visitNextEntry: | | 2.3% {38ms} FileReference>>entries | | 2.3% {38ms} FileSystem>>entriesAt: | | 2.3% {38ms} FileSystem>>entriesAt:do: | | 2.3% {38ms} FileSystem>>entriesAt:ifAbsent:do: | | 2.0% {32ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 2.0% {32ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | | 1.1% {18ms} primitives | 2.8% {45ms} ChrStopwatchPanelM>>prepareBrakelimitLabel | |2.8% {45ms} ChronosManager class>>defaultFontPointSize: | | 2.5% {40ms} FileReference(AbstractFileReference)>>allDirectories | | 2.5% {40ms} SelectVisitor class>>breadthFirst:select: | | 2.5% {40ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.5% {40ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.5% {40ms} BreadthFirstGuide>>show: | | 2.5% {40ms} BreadthFirstGuide>>visitNextEntry: | | 2.5% {40ms} FileReference>>entries | | 2.5% {40ms} FileSystem>>entriesAt: | | 2.5% {40ms} FileSystem>>entriesAt:do: | | 2.5% {40ms} FileSystem>>entriesAt:ifAbsent:do: | | 2.3% {38ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 1.9% {31ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | | 1.3% {21ms} primitives | 2.6% {42ms} ChrStopwatchPanelM>>prepareTimelimitLabel | |2.6% {42ms} ChronosManager class>>defaultFontPointSize: | | 2.3% {37ms} FileReference(AbstractFileReference)>>allDirectories | | 2.3% {37ms} SelectVisitor class>>breadthFirst:select: | | 2.3% {37ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.3% {37ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.3% {37ms} BreadthFirstGuide>>show: | | 2.3% {37ms} BreadthFirstGuide>>visitNextEntry: | | 2.3% {37ms} FileReference>>entries | | 2.3% {37ms} FileSystem>>entriesAt: | | 2.3% {37ms} FileSystem>>entriesAt:do: | | 2.3% {37ms} FileSystem>>entriesAt:ifAbsent:do: | | 1.5% {25ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 1.1% {18ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | 2.6% {42ms} ChrStopwatchPanelM>>prepareTimerButton | |2.4% {39ms} ChrSwitchButtonM class>>createWithAction: | | 2.4% {39ms} ChrSwitchButtonM class(Behavior)>>new | | 2.4% {39ms} ChrSwitchButtonM>>initialize | | 2.2% {36ms} ChronosManager class>>defaultFont | | 2.2% {36ms} ChronosManager class>>defaultFontPointSize: | | 2.2% {36ms} FileReference(AbstractFileReference)>>allDirectories | | 2.2% {36ms} SelectVisitor class>>breadthFirst:select: | | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.2% {36ms} BreadthFirstGuide>>show: | | 2.2% {36ms} BreadthFirstGuide>>visitNextEntry: | | 2.2% {36ms} FileReference>>entries | | 2.2% {36ms} FileSystem>>entriesAt: | | 2.2% {36ms} FileSystem>>entriesAt:do: | | 2.2% {36ms} FileSystem>>entriesAt:ifAbsent:do: | | 1.5% {24ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 1.5% {24ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | 2.2% {36ms} ChrStopwatchPanelM>>prepareDailygoalLabel | |2.2% {36ms} ChronosManager class>>defaultFontPointSize: | | 2.2% {36ms} FileReference(AbstractFileReference)>>allDirectories | | 2.2% {36ms} SelectVisitor class>>breadthFirst:select: | | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | | 2.2% {36ms} BreadthFirstGuide>>show: | | 2.2% {36ms} BreadthFirstGuide>>visitNextEntry: | | 2.0% {32ms} FileReference>>entries | | 2.0% {32ms} FileSystem>>entriesAt: | | 2.0% {32ms} FileSystem>>entriesAt:do: | | 2.0% {32ms} FileSystem>>entriesAt:ifAbsent:do: | | 1.8% {30ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | | 1.7% {28ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | | 1.2% {19ms} primitives | 2.2% {36ms} ChrStopwatchPanelM>>prepareStopwatchLabel | 2.2% {36ms} ChronosManager class>>defaultFontPointSize: | 2.2% {36ms} FileReference(AbstractFileReference)>>allDirectories | 2.2% {36ms} SelectVisitor class>>breadthFirst:select: | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | 2.2% {36ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | 2.2% {36ms} BreadthFirstGuide>>show: | 2.2% {36ms} BreadthFirstGuide>>visitNextEntry: | 2.2% {36ms} FileReference>>entries | 2.2% {36ms} FileSystem>>entriesAt: | 2.2% {36ms} FileSystem>>entriesAt:do: | 2.2% {36ms} FileSystem>>entriesAt:ifAbsent:do: | 2.1% {34ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | 1.9% {31ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | 1.0% {17ms} primitives 4.7% {77ms} ChronosManager class>>defaultFontPointSize: |4.4% {71ms} FileReference(AbstractFileReference)>>allDirectories | 4.4% {71ms} SelectVisitor class>>breadthFirst:select: | 4.4% {71ms} SelectVisitor(AbstractEnumerationVisitor)>>breadthFirst: | 4.4% {71ms} SelectVisitor(AbstractEnumerationVisitor)>>visit:with: | 4.4% {71ms} BreadthFirstGuide>>show: | 4.4% {71ms} BreadthFirstGuide>>visitNextEntry: | 4.4% {71ms} FileReference>>entries | 4.4% {71ms} FileSystem>>entriesAt: | 4.4% {71ms} FileSystem>>entriesAt:do: | 4.4% {71ms} FileSystem>>entriesAt:ifAbsent:do: | 3.5% {57ms} MacStore(FileSystemStore)>>directoryAt:ifAbsent:nodesDo: | 3.1% {51ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: | 2.0% {32ms} primitives 1.4% {22ms} ChrGUIMorph>>centralGUIform 1.4% {22ms} Form class>>fromFileNamed: 1.4% {22ms} Form class>>fromBinaryStream: 1.4% {22ms} ImageReadWriter class>>formFromStream: 1.4% {22ms} PNGReadWriter>>nextImage 1.2% {20ms} PNGReadWriter>>processIDATChunk 1.2% {20ms} PNGReadWriter>>processNonInterlaced **Leaves** 16.4% {267ms} PNGReadWriter>>paethPredictLeft:above:aboveLeft: 15.1% {246ms} InputEventFetcher>>waitForInput 14.3% {232ms} PNGReadWriter>>filterPaeth: 9.9% {160ms} MacStore(DiskStore)>>basicEntry:path:nodesDo: 8.3% {134ms} SoundPlayer class>>playLoop 6.4% {104ms} ZLibReadStream(InflateStream)>>next 3.8% {61ms} Array(SequenceableCollection)>>= 3.1% {51ms} PNGReadWriter>>processNonInterlaced 3.1% {51ms} PNGReadWriter>>filterHorizontal: 2.8% {46ms} ZLibReadStream(InflateStream)>>bitPosition 2.2% {35ms} PNGReadWriter>>filterVertical: 1.7% {27ms} FreeTypeFace class>>fromFile:index: 1.6% {26ms} False>>ifTrue:ifFalse: **Memory** old +20,113,604 bytes young +74,448 bytes used +20,188,052 bytes free +601,016 bytes **GCs** full 5 totalling 294ms (18.0% uptime), avg 59.0ms incr 34 totalling 13ms (1.0% uptime), avg 0.0ms tenures 4 (avg 8 GCs/tenure) root table 0 overflows On Sat, Jan 16, 2016 at 2:31 PM Ben Coman <b...@openinworld.com> wrote: > On Sat, Jan 16, 2016 at 4:03 PM, Dimitris Chloupis > <kilon.al...@gmail.com> wrote: > > Hello Ben :) > > > > First thanks for investing 1 hour of your precious time to look through > my > > code. I really appreciate it . If there is one thing I love about pharo > is > > the super amazing community. > > > > Yes definetly my fault as always :D > > > > I did not know about this profiling, I used it for the creating of my > Morphs > > but it did not occur to me to google like you did and go with profiling > all > > processes. > > > > A huge thank you to latsaben and the rest of you guys. I downgraded down > to > > Pharo 4 and again I agree 5 is the unstable version anyway but I loved > using > > the new tools and could not wait till April for the Pharo 5 release :) > > > > The problem is battling without documentation is very hard and I have > spent > > at least 10 hours trying to understand how taskbar works and I still > fail. > > > > Your code solves my problem , apart from 1. Loading those pngs is > sloowwwww, > > one would expect that accesing the files themselves to get the binary > data > > is what is slow for pharo but no, thats is fast enough. What is slow , > > because I profiled this is converting the binary data to form is > consuming > > a ton of time. The result is that to load a GUI with only 1 mb of pngs > takes > > 1 second. > > What is the practical effect of this that is most concerning? > 1. The time taken loading it the first time after installing from > Catalog Browser ? > 2. The time taken to start it *each* time from World > Chronos > Manager, if you open/close it a lot? > 3. Distributing Chronos Manager as a packaged application? > each time you want to open it > > Not sure if the following will suit your needs, but in the definition > of ChrGUIMorph try moving 'secondsTimerFormCollection' from > instanceVariableNames: to classVariableNames: > > then test by opening/closing the app a few times. After taking a > while opening the first time, subsequent openings seem to be faster. > > > > > Also with your solution I lose the ability to update my taskbar icon, by > the > > way the non optimised code I was using is a direct copy from SystemWindow > > class, which means that class should be optimised too. > > So consider that solution just a problem-isolation step on the way ;). > I had another look because I was intrigued that even though you used > LRUCache for the /icons/ variable, the ifAbsent: block in > #logotinyIcon was being executed anyway. I thought that must be cache > size too small and items bumped out, so as a test I replace LRUCache > with Dictionary, but the the ifAbsent: block was *still* getting > executed (note, this is at steady-state, not startup). So I thought > /icons/ must be getting reset. Investigating by putting the following > at the top of #initializeIcons... > > Transcript crShow: thisContext printString , > ' <-- ', thisContext sender printString, > ' <-- ', thisContext sender sender printString. > > So now this executes every time I open the World menu. And after > ChronosManager is opened, the Transcript scroll rapidly. So everywhere > you do something like this... > icon: ChrStopwatchSettingsPNG new logotinyIcon > where logotinyIcon returns an object, the object created by #new is > thrown away. Worse, #new invokes #initialize and hence > #initializeIcons wipes out your cache every cycle. > > Try making /icons/ a class variable and moving methods like > logotinyIcon to the class side, so instead you do... > icon: ChrStopwatchSettingsPNG logotinyIcon > > Also move #initializeIcons to class side and add a class side > #initialize method to call it. Note that will only be executed when > the class is first loaded, so you will probably need to execute it > manually in your image. > > One thing I'm interested in the choice of LRUCache over Dictionary for > the cache? Did you find Dictionary was taking too much space? > > I didn't try implementing the above yet, but I guessing you'll get the > performance fix while maintaining the flexibility you want. > > cheers -ben > > > Another problem is the scaling of images, really bad with morphic though > > Athens must be better. > > > > Auto completion problems are well knows, sometimes autocompletion does > not > > show all methods, sometimes autocompletion shows every character you > type so > > for example ChronosManager open will show > > ChronosManager o > > ChronosManager op > > ChronosManager ope > > ChronosManager open > > > > Sometimes it shows methods that do not even belong to the class forcing > me > > to use Spotter to find the correct method. Its a a mess. > > > > I am not abandoning pharo, I love it even with its flaws. But I try to > > outsource as much as I can my workflow from pharo to external libraries > and > > apps that are way more mature and efficient for what I am trying to do. > > > > I always inteded to make Blender work with Pharo, I accomplished that > now I > > want to make Unreal engine to work with pharo, so I can make a triangle > of > > love, Blender for asset creation, Unreal for real time rendering of 2d > and > > 3d graphics , Pharo as the brain of the logic and advanced scripting of > the > > other 2. This is was my dream and goal all along. So I will be moving my > GUI > > to Unreal that will allow me much more advanced and performance > orientated > > features that mix 2d with 3d but I will keeping my main logic in pharo. > > > > > > On Sat, Jan 16, 2016 at 6:35 AM Ben Coman <b...@openinworld.com> wrote: > >> > >> On Sat, Jan 16, 2016 at 7:28 AM, Dimitris Chloupis > >> <kilon.al...@gmail.com> wrote: > >> > taskbarTask (self valueOfProperty: #noTaskbarTask ifAbsent: [ false ]) > >> > ifTrue: [ ^ nil ]. ^ nil "TaskbarTask morph: self state: self > >> > taskbarState > >> > icon: self taskbarIcon label: self taskbarLabel" > >> > > >> > The uncommented part was the one that was slowing me down, its a copy > >> > from > >> > SystemWindow, on a new image of Pharo consumption drops to 15% but > still > >> > have issues with Nautilus etc. > >> > > >> > latsabben at Slack also recommended caching which helped also > >> > > >> > taskbarTask "myTask := nil." myTask ifNil: [ myTask := TaskbarTask > >> > morph: > >> > self state: self taskbarState icon: self taskbarIcon label: self > >> > taskbarLabel ]. myTask label: self taskbarLabel. ^myTask > >> > > >> > Anyway I decided to port my project to C++ and Unreal Engine because I > >> > have > >> > many issues with Pharo speed wise > >> > >> See my other post, in about an hour I moved your App from 55% cpu > >> usage on my machine to 7%, only 1% above our 6% idle. We *do* need > >> to address that minimum idle, but its at the VM level since in-Image > >> profiling shows 90% time in ProcessorScheduler class>>idleProcess. So > >> to me the Image seems not too bad performance wise > >> > >> > and stability wise with Pharo 5. > >> > >> Well, you are talking about bleeding edge alpha software. > >> > >> > Plus many IDE features I miss like proper auto completion etc. > >> > >> You've probably mentioned this somewhere previously, but in another > >> thread could you leave us with a summary of what is missing from auto > >> completion. > >> > >> > To be fair I tried to make custom gui with python and it was even > slower > >> > in > >> > the past. > >> > > >> > So its clear I need a high performance language + API, because I will > be > >> > building a very heavy GUI (many more animations) and I would like > also > >> > some > >> > fast 3d functionality too. > >> > >> good luck with it. > >> cheers -ben > >> > >> > >> > > >> > On Sat, Jan 16, 2016 at 1:07 AM Sven Van Caekenberghe <s...@stfx.eu> > >> > wrote: > >> >> > >> >> > >> >> > On 15 Jan 2016, at 23:30, Dimitris Chloupis <kilon.al...@gmail.com > > > >> >> > wrote: > >> >> > > >> >> > taskbar was the problem, damn pharo gui is a huge pain in the hat. > >> >> > >> >> How so ? > >> >> > >> >> > On Fri, Jan 15, 2016 at 11:32 PM Dimitris Chloupis > >> >> > <kilon.al...@gmail.com> wrote: > >> >> > ITs not the step, I removed the step as I said in my first post. > >> >> > Still > >> >> > 30% cpu consumption > >> >> > > >> >> > The images are PNGs and RGBA , 8bit > >> >> > > >> >> > > >> >> > On Fri, Jan 15, 2016 at 10:54 PM Hilaire <hila...@drgeo.eu> wrote: > >> >> > It depends on what you are doing in a step, but 1s step should not > >> >> > hurt. > >> >> > May be the problem is somewhere else. > >> >> > With DrGeo, I noted Athens is faster to BitBlt with bitmap > operations > >> >> > (in my case, only scaling and displaying a From in a DrGeo canvas). > >> >> > Also, do your bitmaps come with 32 bits depth? > >> >> > > >> >> > -- > >> >> > Dr. Geo > >> >> > http://drgeo.eu > >> >> > > >> >> > > >> >> > > >> >> > >> >> > >> > > >> > > > >