Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 3 participants
- 144636 messages
Re: [Pharo-dev] red banner and links with safari?
by Ben Coman
I guess the only real fix for the https pages produced to reference https
stylesheets.
cheers -ben
On Mon, Nov 23, 2015 at 1:58 AM, Peter Uhnák <i.uhnak(a)gmail.com> wrote:
> > The question now is: what do we need to fix to make it work?
>
>
> â
> (or just open console in your favorite browser (chrome))
>
> Peter
>
Nov. 22, 2015
Re: [Pharo-dev] Kind of RBRenameMethodRefactoring but for closures?
by Mariano Martinez Peck
>
>
>>
>> Yes. I think it is possible to work around it by using the
>> dictionary itself, storing the node selector in it in the replace:
>> pattern and retrieving it in the with: pattern.
>>
>> rewriter
>> replace: ('`#oldSelector `{:node :dic | (node value
>> isSymbol and: [node value matchesRegex: ''.*oldSelector.*''])
>> ifTrue: [dic at: #selector put: node value. true] ifFalse: [false] }')
>> with: ('`{:dic | RBLiteralNode value: ((dic at:
>> #selector) copyReplaceAll: ''oldSelector'' with: ''newSelector'')
>> asSymbol }').
>>
>>
>> Wow, that's very cool. I wasn't aware that I could pass arguments (like
>> the dict in this case). This is powerful.
>>
>
> Yes, quite significant. Also the fact the dictionary is cleared for each
> match (so that it can be reused for the next match in the same ast).
>
>
awesome.
> Thank you RB Jedi.
>>
>
> I've had the guidance of John Brant (and spent some time over the SmaCC
> code where he uses it)...
>
> Now, maybe correcting RB in Gemstone is something to do, as well.
>>
>>
>> Yes. So with the dict workaround you said, it DID work, but when I
>> continue a little more and I found out where was the closure being
>> generated, and that is RBPatternBlockNode >> #createBlockFor:
>> And yeah, the way it was being generated the closure ("source
>> evalauted") was binding "self" to nil. I found a way to make it bind
>> the real self and that worked too. So...time to fork RB for GemStone and
>> commit the fix :)
>>
>
> You're now the maintainer of RB for GemStone! Congratulations :)
>
>
ahhahahaha.
You know what is funny? I run all AST-Tests-Core from Pharo and NONE halt
on #createBlockFor: ...
I even run all those from Refactoring-Tests-Core.
*So..it seems there is not tests that covers the usage of #createBlockFor:
:(*
> BTW, do you image other cases like this?
>>
>
> You mean storing those RB rules? I try to collect them if I see some (or
> participate to), or remember where I see them.
>
>
No, I mean the compilation of block closures that would try to bind "self".
Anyway, I will search if I find more.
> I used to know where the RBRewriteTree chapter was in the Pharo books, but
> it seems to have disappeared, so I have recreated a copy that I'll try to
> update.
>
Thanks, please share it with me when you made it because I could not find
it weeks ago.
>
> Thanks!
>>
>
> You're welcome. You are giving opportunities to improve which is what I
> need (need to practice, need to practice, need to practice...).
>
>
ahahahahahha :)
> I have ideas for Mark Rizun's tool, but I don't have the time to work on
> them.
>
> Thierry
>
>
Thanks !
--
Mariano
http://marianopeck.wordpress.com
Nov. 22, 2015
Re: [Pharo-dev] Kind of RBRenameMethodRefactoring but for closures?
by Thierry Goubier
Le 22/11/2015 19:56, Mariano Martinez Peck a écrit :
>
>
> On Sat, Nov 21, 2015 at 7:07 AM, Thierry Goubier
> <thierry.goubier(a)gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
>
> Hi Mariano,
>
> Le 20/11/2015 20:58, Mariano Martinez Peck a écrit :
>
> Thierry,
>
> Sorry to bother again. Unfortunately, RB does not work out of
> the box in
> GemStone .... only the formatter part. grrr.
>
>
> There is maybe a message to send to the maintainer of RB in Gemstone :)
>
>
> Thanks Thierry. Yes, I talked with Dale and the only "official"
> usage/port of RB is actually the formatter ;)
:(
> Anyway, I am trying to make it work, and it's failing in this
> easy example:
>
> /| tree rewriter |/
> /tree := RBParser parseMethod: 'DoIt ^ [:proxy | proxy at:
> #oldSelector.
> ]'./
> /rewriter := RBParseTreeRewriter new./
> /rewriter /
> /replace: ('`#oldSelector `{:node | node value isSymbol and:
> [node value
> matchesRegex: ''.*oldSelector.*''] }')/
> /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
> ''oldSelector'' with: ''newSelector'') asSymbol }')./
> /rewriter executeTree: tree./
> /rewriter tree newSource/
> And the problem is the line:
>
> /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
> ''oldSelector'' with: ''newSelector'') asSymbol }')./
>
> which gets translated to:
>
> [ :aDictionary |
> RBLiteralNode
> value:
> ((*self* lookupMatchFor: '`#oldSelector' in: aDictionary)
> value
> copyReplaceAll: 'oldSelector'
> with: 'newSelector') asSymbol ]
>
> The problem in GemStone is that that "self" is binded to nil and
> not to
> the receiver instance (RBPatternBlockNode). And so I get a Nil dnu..
> *And I don't know how that closure is finally generated.*
>
> The message node:
>
> /(*self* lookupMatchFor: '`#oldSelector' in: aDictionary) /
>
> Its generated in:
>
> RBPatternBlockNode >> constructLookupNodeFor: aString in:
> aRBBlockNode
> | argumentNode |
> argumentNode := RBLiteralNode value: aString.
>
> ^RBMessageNode
> receiver:* (RBVariableNode named: 'self')*
> selector: #lookupMatchFor:in:
> arguments: (Array with: argumentNode with: aRBBlockNode
> arguments last)
>
> Any ideas?
>
>
> Yes. I think it is possible to work around it by using the
> dictionary itself, storing the node selector in it in the replace:
> pattern and retrieving it in the with: pattern.
>
> rewriter
> replace: ('`#oldSelector `{:node :dic | (node value
> isSymbol and: [node value matchesRegex: ''.*oldSelector.*''])
> ifTrue: [dic at: #selector put: node value. true] ifFalse: [false] }')
> with: ('`{:dic | RBLiteralNode value: ((dic at:
> #selector) copyReplaceAll: ''oldSelector'' with: ''newSelector'')
> asSymbol }').
>
>
> Wow, that's very cool. I wasn't aware that I could pass arguments (like
> the dict in this case). This is powerful.
Yes, quite significant. Also the fact the dictionary is cleared for each
match (so that it can be reused for the next match in the same ast).
> Thank you RB Jedi.
I've had the guidance of John Brant (and spent some time over the SmaCC
code where he uses it)...
> Now, maybe correcting RB in Gemstone is something to do, as well.
>
>
> Yes. So with the dict workaround you said, it DID work, but when I
> continue a little more and I found out where was the closure being
> generated, and that is RBPatternBlockNode >> #createBlockFor:
> And yeah, the way it was being generated the closure ("source
> evalauted") was binding "self" to nil. I found a way to make it bind
> the real self and that worked too. So...time to fork RB for GemStone and
> commit the fix :)
You're now the maintainer of RB for GemStone! Congratulations :)
> BTW, do you image other cases like this?
You mean storing those RB rules? I try to collect them if I see some (or
participate to), or remember where I see them.
I used to know where the RBRewriteTree chapter was in the Pharo books,
but it seems to have disappeared, so I have recreated a copy that I'll
try to update.
> Thanks!
You're welcome. You are giving opportunities to improve which is what I
need (need to practice, need to practice, need to practice...).
I have ideas for Mark Rizun's tool, but I don't have the time to work on
them.
Thierry
Nov. 22, 2015
Re: [Pharo-dev] Rules
by Yuriy Tymchuk
Hi.
The rule is correct. Sending a different message to super may be confusing. In this case you are in âprintOn:â method and you are sending âprintOn:nextPutAll:â to super. The idea is that you have to send âprintOn:nextPutAll:â to self and then either it will invoke the super one, you there will be an overridden method in your current class.
Secondly, there is an issue with âsends unkown selectorâ. Iâve also noticed it recently. I think that it happens because the rule has a special cace, and I messed up something with refresh. This is the next thing on my TODO list.
Cheers.
Uko
> On 22 Nov 2015, at 16:33, Marcus Denker <marcus.denker(a)inria.fr> wrote:
>
>
>> On 22 Nov 2015, at 12:20, stepharo <stepharo(a)free.fr> wrote:
>>
>> With the following (broken) definition
>>
>>
>> : aStream
>> super printOn: aStream
>> aStream nextPutAll: '(', faces printString , ')'
>>
>> I got this strange rule:
>>
>> Rewrite super messages to self messages when both refer to same method
>>
>> I do not get it and it looks really suspicious to me.
>> Any suggestions?
>
> The rule is meant to catch the case when when âsuperâ can be âselfâ as there is no #printOn:
> defined in the class.
>
> But here it looks like it is wrong: it would be an infinite loop.
>
> I think it could be related to this other bug: I have seen that the rules are not correctly updated
> when you add methods. (I wanted to add an issue for that but did not yet). E.g. I often get
> a âsends unkown selectorâ for self sends and then I check â> method is there, I just added it!
>
> So here this means that you added a new printOn:, the rules do not update, and it thinks
> that there is no printOn:.
>
> So the real bug is that added methods need to be taken into account by QA.
>
> Marcus
Nov. 22, 2015
Re: [Pharo-dev] Kind of RBRenameMethodRefactoring but for closures?
by Mariano Martinez Peck
On Sat, Nov 21, 2015 at 7:07 AM, Thierry Goubier <thierry.goubier(a)gmail.com>
wrote:
> Hi Mariano,
>
> Le 20/11/2015 20:58, Mariano Martinez Peck a écrit :
>
>> Thierry,
>>
>> Sorry to bother again. Unfortunately, RB does not work out of the box in
>> GemStone .... only the formatter part. grrr.
>>
>
> There is maybe a message to send to the maintainer of RB in Gemstone :)
>
>
Thanks Thierry. Yes, I talked with Dale and the only "official" usage/port
of RB is actually the formatter ;)
> Anyway, I am trying to make it work, and it's failing in this easy example:
>>
>> /| tree rewriter |/
>> /tree := RBParser parseMethod: 'DoIt ^ [:proxy | proxy at: #oldSelector.
>> ]'./
>> /rewriter := RBParseTreeRewriter new./
>> /rewriter /
>> /replace: ('`#oldSelector `{:node | node value isSymbol and: [node value
>> matchesRegex: ''.*oldSelector.*''] }')/
>> /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
>> ''oldSelector'' with: ''newSelector'') asSymbol }')./
>> /rewriter executeTree: tree./
>> /rewriter tree newSource/
>> And the problem is the line:
>>
>> /with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
>> ''oldSelector'' with: ''newSelector'') asSymbol }')./
>>
>> which gets translated to:
>>
>> [ :aDictionary |
>> RBLiteralNode
>> value:
>> ((*self* lookupMatchFor: '`#oldSelector' in: aDictionary) value
>> copyReplaceAll: 'oldSelector'
>> with: 'newSelector') asSymbol ]
>>
>> The problem in GemStone is that that "self" is binded to nil and not to
>> the receiver instance (RBPatternBlockNode). And so I get a Nil dnu..
>> *And I don't know how that closure is finally generated.*
>>
>> The message node:
>>
>> /(*self* lookupMatchFor: '`#oldSelector' in: aDictionary) /
>>
>> Its generated in:
>>
>> RBPatternBlockNode >> constructLookupNodeFor: aString in: aRBBlockNode
>> | argumentNode |
>> argumentNode := RBLiteralNode value: aString.
>>
>> ^RBMessageNode
>> receiver:* (RBVariableNode named: 'self')*
>> selector: #lookupMatchFor:in:
>> arguments: (Array with: argumentNode with: aRBBlockNode arguments last)
>>
>> Any ideas?
>>
>
> Yes. I think it is possible to work around it by using the dictionary
> itself, storing the node selector in it in the replace: pattern and
> retrieving it in the with: pattern.
>
> rewriter
> replace: ('`#oldSelector `{:node :dic | (node value
> isSymbol and: [node value matchesRegex: ''.*oldSelector.*'']) ifTrue: [dic
> at: #selector put: node value. true] ifFalse: [false] }')
> with: ('`{:dic | RBLiteralNode value: ((dic at: #selector)
> copyReplaceAll: ''oldSelector'' with: ''newSelector'') asSymbol }').
>
>
Wow, that's very cool. I wasn't aware that I could pass arguments (like the
dict in this case). This is powerful.
Thank you RB Jedi.
> Now, maybe correcting RB in Gemstone is something to do, as well.
>
>
Yes. So with the dict workaround you said, it DID work, but when I continue
a little more and I found out where was the closure being generated, and
that is RBPatternBlockNode >> #createBlockFor:
And yeah, the way it was being generated the closure ("source evalauted")
was binding "self" to nil. I found a way to make it bind the real self and
that worked too. So...time to fork RB for GemStone and commit the fix :)
BTW, do you image other cases like this?
Thanks!
Regards,
>
> Thierry
>
> thanks in advance,
>>
>>
>> On Mon, Nov 9, 2015 at 2:39 PM, Thierry Goubier
>> <thierry.goubier(a)gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
>>
>> Le 09/11/2015 17:38, Mariano Martinez Peck a écrit :
>>
>> Thierry, I have a last question. My last requirement will
>> basically be
>> to find ANY node that would match the regex *oldSelector* and
>> rename it
>> to *newSelector* being that.. a literal string, a literal symbol,
>> a
>> message send, a tempVar name, a comment, etc... I guess there is a
>> simpler way that defining rewrite for each type of node right?
>> I can always do a "(methodSource substrings detect: [:each | each
>> matches: '*oldSelector'] ifNone: [#()] ) each2: [:each2 |
>> copReplace.
>> .... ]
>>
>>
>> I think that if it is really everywhere, then it may works better to
>> just do text replace (methodSource copyReplaceAll: 'oldSelector'
>> with: 'newSelector').
>>
>> But remember that it will touch everything (pragmas, varNames,
>> comments, etc.)
>>
>> but RB is probably better.
>>
>>
>> It gives you more control to what you will change. But then you will
>> have to write rewrites for all types of nodes (around 6 or 7?).
>>
>> Any clues in this last requirement?
>>
>>
>> Well, one thing which may be interesting would be to consider
>> encapsulating the rewrites in refactoring commands, and bring them
>> as a composite change, so that you could launch a rewrite, recover
>> all those method changes, apply (execute) them, check the result
>> with the possibility of undoing them.
>>
>> But I'm not familiar with that part of RB. I do consider it could
>> become significant with EPICEA. It has been a long term project to
>> have AltBrowser make all coding actions as refactoring commands so
>> that EPICEA could log them properly, but its only partly there (and
>> has been for years now)... and EPICEA is not yet here as well (but
>> could be soon).
>>
>> Thierry
>>
>>
>>
>>
>> --
>> Mariano
>> http://marianopeck.wordpress.com
>>
>
>
>
--
Mariano
http://marianopeck.wordpress.com
Nov. 22, 2015
Re: [Pharo-dev] Rules
by Peter Uhnák
>> printOn: aStream
>> super printOn: aStream
>> aStream nextPutAll: '(', faces printString , ')'
Because you forgot dot after the first line.
This is why I always use autoformatting to catch these kind of stupid
mistakes (happens to me a lot).
Nov. 22, 2015
Jenkins job @ ci.inria.fr
by Lucas Godoy
Hi everyone
I have two jobs in ci.inria.fr for the project Tracks. One is for Pharo 3.0
and another for Pharo 4.0. Since Tracks requires Epicea to run and Epicea
is no longer mantained for Pharo 3.0, the Tracks job for Pharo 3.0 is
failing and it doesn't make sense to keep it. I only want to keep the job
for Pharo 4.0.
This is the URL of the job:
<http://goog_1488548907>
https://ci.inria.fr/pharo-contribution/job/Tracks/PHARO=30,VERSION=developm…
I haven't logged-in in Jenkins in quite a while and now my authentication
fails. I may have just forgotten my password or my credentials are expired.
Can somebody at INRIA delete the Tracks job for Pharo 3.0 or reset my
password so I can delete it, please? Thanks in advance!
--
------------------------------------------
Lucas Godoy
------------------------------------------
Nov. 22, 2015
Re: [Pharo-dev] red banner and links with safari?
by Peter Uhnák
> The question now is: what do we need to fix to make it work?
â
(or just open console in your favorite browser (chrome))
Peter
Nov. 22, 2015
Re: [Pharo-dev] A plea for responsive coding
by Dimitris Chloupis
Yeah I was joking too, well I was semi serious more like it. Of course I
care about performance, but I am willing to be forgiving with Pharo ,
everything has its own issues and doing graphics with Pharo beats doing
graphics with C/C++ anyday. Debugging C++ code kills my inner child.
Yes I think I will be fine, we were just discussing with Stephan on slack
about slow down he found with Checkboxmorph he also thought that the
reference of the forms (on ,off, pressed , depressed) was slow for some
reason but I found out that it was the initialisation of the checkboxmoprh
that it was much slower , reference the morphs gave me 2 million request
per second. So referencing the forms is blazing fast.
So it looks like the slow down is mainly creating the form, as soon as
creating the form Morphic is very fast. So its not that bad and I am sure I
will be fine. But I promise to keep digging. Morphic has this hot and cold
attitude , that when you expect it to be slow is blazzing fast and when you
expect it to be fast its hog slow. I think also that most likely PNGReader
could be optimised to be faster, but for now thats outside my area of
expertise.
On Sun, Nov 22, 2015 at 7:16 PM Tudor Girba <tudor(a)tudorgirba.com> wrote:
> Hi,
>
> I was making a joke given the way the discussion turned out:
> - you said that something was slow
> - then Stef asked you if you are caching the forms instead of PNGs
> - then you said you do not
> - then Stef asked you why not
> - then you said that you were not focused on making things fast
>
> Anyway, maybe it was funny just for me :).
>
> Morph is rather slow indeed, but displaying a handful of PNGs should not
> kill it either. But, it seems you narrowed the problem down. In my little
> snippet, I provided a cache. By the look of it, I think that should address
> that problem. Could you let us know if this works out for you?
>
> Cheers,
> Doru
>
>
> > On Nov 22, 2015, at 4:24 PM, Dimitris Chloupis <kilon.alios(a)gmail.com>
> wrote:
> >
> > I realize you trying to help, and thank you very much. Nothing I have
> done would be possible without your help. But also you must realize I am
> not you and not as familiar with Pharo as you are. Also when I say that I
> do something that does not mean I ignore your advice. At the moment I was
> not aware of the problem , now that I am aware I have profiled it , I have
> isolated the exact method (is in the PNGReader class) and I have already a
> fix in mind, I even created an issue not to forget about it
> >
> > https://github.com/kilon/ChronosManager/issues/15
> >
> > all these have happened way before your first replied to me.
> >
> > I am very relaxed, as a matter of fact I am quite happy with my pharo
> experience so far. I was never naive enough to expect Morphic to be fast,
> there is a reason why graphics code is predominately coded in C/C++ and why
> I have been an active supporter of SDL graphics support for Pharo in the
> past.
> >
> > I am willing to learn but those things take time. And my reply was a bit
> on the comic side if that has not been obvious so far ;)
> >
> >
> >
> > On Sun, Nov 22, 2015 at 5:13 PM stepharo <stepharo(a)free.fr> wrote:
> > You should relax a bit.
> > We were trying to help.
> > Morphic is slow and strange and we are working on new generation.
> > Now profile a bit your application to see what you are doing may be you
> are redrawing too much or triggering something that is costly.
> > So it depends what you are doing. the step method of all the morphs is
> invoked every refresh cycle so.
> >
> > Stef
> >
> >
> >> really you ask me why I am complaining that loading a form from a 2kb
> png image, AND I REPEAT , 2KB IMAGE ,for each morphic step brings a whole
> GUI system to its knees with 5 instances ?
> >>
> >> I complain, which I did not complain by the way but your post inspires
> me to complain a lot now, because tectonic plates find Pharo handling of
> images so slow they decided to go out for coffee.
> >>
> >> I also complain because I live in 2015 where my main open source app ,
> blender can handle loading a 300 mb blend file in under a second. And I
> consider Blender one of the least performant 3d apps out there. Thats a
> file more 100.000 times larger than the pathetic small png i am loading
> during stepping.
> >>
> >> And on top of that , is also my first try at creating something based
> on png images in pharo and I am slapped in the face for daring to deliver
> code that is not right. Sorry but you guys make no sense.
> >>
> >>
> >> This is how I store pngs in a method -->
> http://smalltalkhub.com/#!/~peteruhnak/IconFactory
> >>
> >> But I probably will abandon that solution too and rely on loading
> external files directly since I dont like overcrowding my method sources
> with image data. If that make things slower , so be it, I will have to live
> with the idea that Pharo is not fast and try to work on what I can do with
> it. I dont mind limitations, I do mind being told that I complain when I
> clearly dont.
> >>
> >>
> >>
> >> On Sun, Nov 22, 2015 at 4:37 PM Tudor Girba <tudor(a)tudorgirba.com>
> wrote:
> >> Then why do you âcomplain" about the code being slow? :)
> >>
> >> Seriously, how do you store the PNG file in the method? Here is an
> example of how to store the form of a PNG:
> >>
> >> form := PNGReadWriter formFromFileNamed: aPngFile.
> >> iconName := aPngFile basenameWithoutExtension.
> >> methodSource :=
> >> iconName , Character cr asString ,
> >> '^ self icons
> >> at: #', iconName,
> >> 'ifAbsentPut: [',
> >> form storeString,
> >> ']'.
> >> targetClass class compile: methodSource classified: âiconsâ.
> >>
> >> This will compile the picture in a âiconNameâ method in a
> âtargetClassâ. The code also relies on an âiconsâ getter in the
> âtargetClassâ that should cache these forms. Like this, you only load the
> form once.
> >>
> >> Is this enough for you?
> >>
> >> Cheers,
> >> Doru
> >>
> >>
> >> > On Nov 22, 2015, at 2:56 PM, Dimitris Chloupis <kilon.alios(a)gmail.com>
> wrote:
> >> >
> >> > because making something work for me comes way before making
> something work fast.
> >> >
> >> > On Sun, Nov 22, 2015 at 3:50 PM stepharo <stepharo(a)free.fr> wrote:
> >> > But why don't you manipulate Forms instead of PNGs. Converting from
> PNGs to Forms should be done only once.
> >> >
> >> > Stef
> >> >
> >> > Le 22/11/15 11:53, Dimitris Chloupis a écrit :
> >> >> here is the tricky part , I am willing to bet that the slow down
> happens because of the stepping of the seconds indicator.
> >> >>
> >> >> The one thing I forgot to mention is that I dont load my images from
> external files, the images are already converted to method sources ,
> strings , with Peter's IconFactory library. Still the PNGReader class tries
> to convert those string streams to forms and is where most of the time is
> consumed. The reason I chose this approach was in hope of a speed up so
> pharo does not waste time opening and closing files.
> >> >>
> >> >> In the stepping of the seconds indicator I recreate the form in each
> step , depending on the seconds. I could optomise that part by having all
> images of the animation loaded into seperate forms during initialisation
> and just use the reference of the correct form during stepping that should
> speed things up a lot.
> >> >>
> >> >> Overall 170ms for opening that GUI is not so bad for a dynamic GC
> language. Taking into account that this is mostly pharo code , unlike
> python that it would be using a C lib to speed things up. I am a happy
> Morphic customer :)
> >> >>
> >> >> On Sun, Nov 22, 2015 at 12:39 PM Thierry Goubier <
> thierry.goubier(a)gmail.com> wrote:
> >> >> Le 22/11/2015 11:27, Dimitris Chloupis a écrit :
> >> >> > tried with ChronosManager
> >> >> >
> >> >> > [ ChronosManager open ] bench
> >> >> >
> >> >> > 5.6 per second
> >> >> >
> >> >> > it opened around 30 instances and Morphic was crawling.
> >> >> >
> >> >> > I profiled it and it reports that it spends a total 170ms which is
> >> >> > consistent with bench. Around 50ms is spent only for loading the
> image
> >> >> > of the secondary panel and from what I have seen loading the
> images and
> >> >> > the font accounts around 90% of the time spent and then rest 10% is
> >> >> > actually morphic + logic.
> >> >>
> >> >> If I understand you well, what you have is:
> >> >>
> >> >> - ChronosManager takes 170ms to open, including external resources
> >> >> loading time (which is SSD/HD dependent).
> >> >>
> >> >> - The whole world performance degrades with many ChronosManager
> >> >> instances loaded? (Moving one around probably forces others to
> refresh
> >> >> as well).
> >> >>
> >> >> What could be nice is to profile rendering time as well (but, if your
> >> >> first render time is included in the 10% of 170ms you quote, then it
> is
> >> >> probably fine).
> >> >>
> >> >> Would you like to try benchmarking rendering one ChronosManager
> instance
> >> >> when you have 30 instances opened / only one instance opened?
> >> >>
> >> >> > So from the looks of it , it looks like Morphic does not perform
> well
> >> >> > with loaded images and external files.
> >> >>
> >> >> This is a clear win if you cache those (i.e. have a LRU cache holding
> >> >> forms and fonts, filled upon first load, reused over subsequent
> loads).
> >> >>
> >> >> Thierry
> >> >>
> >> >> >
> >> >> >
> >> >> > On Sun, Nov 22, 2015 at 11:34 AM Thierry Goubier
> >> >> > <thierry.goubier(a)gmail.com <mailto:thierry.goubier@gmail.com>>
> wrote:
> >> >> >
> >> >> > Hi all,
> >> >> >
> >> >> > I would like to ask you, all of you, something significant
> when doing
> >> >> > GUI coding:
> >> >> >
> >> >> > Pay attention to performance!
> >> >> >
> >> >> > With the current state of our technology (Morphic, Bloc,
> whatever comes
> >> >> > next) your target should be one hundred milliseconds (100 ms),
> for
> >> >> > opening / redisplaying the widget.
> >> >> >
> >> >> > Why?
> >> >> >
> >> >> > - Because, in 10ms, Morphic can open and layout dozens of
> Morphs on a
> >> >> > low-end machine (1.4GHz Celeron).
> >> >> >
> >> >> > - Because most of you work on 3GHz+ i7 Macbook Pro (so, at 10x
> the cpu
> >> >> > performance of that said Celeron).
> >> >> >
> >> >> > - Because you are not to reproduce the past: that your current
> tools are
> >> >> > slow is no excuse.
> >> >> >
> >> >> > - Because you now have well designed core widgets (FT) that
> behaves in
> >> >> > O(1) and opens fully loaded in 10's of milliseconds
> >> >> >
> >> >> > So, profile and clean your code! Eliminate unneeded caches!
> Clean your
> >> >> > architectures! Avoid or mark slow code and bottlenecks!
> >> >> >
> >> >> > And bring numbers when you want to criticize the performance
> of a
> >> >> > subsystem...
> >> >> >
> >> >> > Thierry
> >> >> >
> >> >>
> >> >>
> >> >
> >>
> >> --
> >> www.tudorgirba.com
> >>
> >> "Every now and then stop and ask yourself if the war you're fighting is
> the right one."
> >>
> >>
> >>
> >>
> >
>
> --
> www.tudorgirba.com
>
> "Presenting is storytelling."
>
>
>
Nov. 22, 2015
Re: [Pharo-dev] A plea for responsive coding
by Tudor Girba
Hi,
I was making a joke given the way the discussion turned out:
- you said that something was slow
- then Stef asked you if you are caching the forms instead of PNGs
- then you said you do not
- then Stef asked you why not
- then you said that you were not focused on making things fast
Anyway, maybe it was funny just for me :).
Morph is rather slow indeed, but displaying a handful of PNGs should not kill it either. But, it seems you narrowed the problem down. In my little snippet, I provided a cache. By the look of it, I think that should address that problem. Could you let us know if this works out for you?
Cheers,
Doru
> On Nov 22, 2015, at 4:24 PM, Dimitris Chloupis <kilon.alios(a)gmail.com> wrote:
>
> I realize you trying to help, and thank you very much. Nothing I have done would be possible without your help. But also you must realize I am not you and not as familiar with Pharo as you are. Also when I say that I do something that does not mean I ignore your advice. At the moment I was not aware of the problem , now that I am aware I have profiled it , I have isolated the exact method (is in the PNGReader class) and I have already a fix in mind, I even created an issue not to forget about it
>
> https://github.com/kilon/ChronosManager/issues/15
>
> all these have happened way before your first replied to me.
>
> I am very relaxed, as a matter of fact I am quite happy with my pharo experience so far. I was never naive enough to expect Morphic to be fast, there is a reason why graphics code is predominately coded in C/C++ and why I have been an active supporter of SDL graphics support for Pharo in the past.
>
> I am willing to learn but those things take time. And my reply was a bit on the comic side if that has not been obvious so far ;)
>
>
>
> On Sun, Nov 22, 2015 at 5:13 PM stepharo <stepharo(a)free.fr> wrote:
> You should relax a bit.
> We were trying to help.
> Morphic is slow and strange and we are working on new generation.
> Now profile a bit your application to see what you are doing may be you are redrawing too much or triggering something that is costly.
> So it depends what you are doing. the step method of all the morphs is invoked every refresh cycle so.
>
> Stef
>
>
>> really you ask me why I am complaining that loading a form from a 2kb png image, AND I REPEAT , 2KB IMAGE ,for each morphic step brings a whole GUI system to its knees with 5 instances ?
>>
>> I complain, which I did not complain by the way but your post inspires me to complain a lot now, because tectonic plates find Pharo handling of images so slow they decided to go out for coffee.
>>
>> I also complain because I live in 2015 where my main open source app , blender can handle loading a 300 mb blend file in under a second. And I consider Blender one of the least performant 3d apps out there. Thats a file more 100.000 times larger than the pathetic small png i am loading during stepping.
>>
>> And on top of that , is also my first try at creating something based on png images in pharo and I am slapped in the face for daring to deliver code that is not right. Sorry but you guys make no sense.
>>
>>
>> This is how I store pngs in a method --> http://smalltalkhub.com/#!/~peteruhnak/IconFactory
>>
>> But I probably will abandon that solution too and rely on loading external files directly since I dont like overcrowding my method sources with image data. If that make things slower , so be it, I will have to live with the idea that Pharo is not fast and try to work on what I can do with it. I dont mind limitations, I do mind being told that I complain when I clearly dont.
>>
>>
>>
>> On Sun, Nov 22, 2015 at 4:37 PM Tudor Girba <tudor(a)tudorgirba.com> wrote:
>> Then why do you âcomplain" about the code being slow? :)
>>
>> Seriously, how do you store the PNG file in the method? Here is an example of how to store the form of a PNG:
>>
>> form := PNGReadWriter formFromFileNamed: aPngFile.
>> iconName := aPngFile basenameWithoutExtension.
>> methodSource :=
>> iconName , Character cr asString ,
>> '^ self icons
>> at: #', iconName,
>> 'ifAbsentPut: [',
>> form storeString,
>> ']'.
>> targetClass class compile: methodSource classified: âiconsâ.
>>
>> This will compile the picture in a âiconNameâ method in a âtargetClassâ. The code also relies on an âiconsâ getter in the âtargetClassâ that should cache these forms. Like this, you only load the form once.
>>
>> Is this enough for you?
>>
>> Cheers,
>> Doru
>>
>>
>> > On Nov 22, 2015, at 2:56 PM, Dimitris Chloupis <kilon.alios(a)gmail.com> wrote:
>> >
>> > because making something work for me comes way before making something work fast.
>> >
>> > On Sun, Nov 22, 2015 at 3:50 PM stepharo <stepharo(a)free.fr> wrote:
>> > But why don't you manipulate Forms instead of PNGs. Converting from PNGs to Forms should be done only once.
>> >
>> > Stef
>> >
>> > Le 22/11/15 11:53, Dimitris Chloupis a écrit :
>> >> here is the tricky part , I am willing to bet that the slow down happens because of the stepping of the seconds indicator.
>> >>
>> >> The one thing I forgot to mention is that I dont load my images from external files, the images are already converted to method sources , strings , with Peter's IconFactory library. Still the PNGReader class tries to convert those string streams to forms and is where most of the time is consumed. The reason I chose this approach was in hope of a speed up so pharo does not waste time opening and closing files.
>> >>
>> >> In the stepping of the seconds indicator I recreate the form in each step , depending on the seconds. I could optomise that part by having all images of the animation loaded into seperate forms during initialisation and just use the reference of the correct form during stepping that should speed things up a lot.
>> >>
>> >> Overall 170ms for opening that GUI is not so bad for a dynamic GC language. Taking into account that this is mostly pharo code , unlike python that it would be using a C lib to speed things up. I am a happy Morphic customer :)
>> >>
>> >> On Sun, Nov 22, 2015 at 12:39 PM Thierry Goubier <thierry.goubier(a)gmail.com> wrote:
>> >> Le 22/11/2015 11:27, Dimitris Chloupis a écrit :
>> >> > tried with ChronosManager
>> >> >
>> >> > [ ChronosManager open ] bench
>> >> >
>> >> > 5.6 per second
>> >> >
>> >> > it opened around 30 instances and Morphic was crawling.
>> >> >
>> >> > I profiled it and it reports that it spends a total 170ms which is
>> >> > consistent with bench. Around 50ms is spent only for loading the image
>> >> > of the secondary panel and from what I have seen loading the images and
>> >> > the font accounts around 90% of the time spent and then rest 10% is
>> >> > actually morphic + logic.
>> >>
>> >> If I understand you well, what you have is:
>> >>
>> >> - ChronosManager takes 170ms to open, including external resources
>> >> loading time (which is SSD/HD dependent).
>> >>
>> >> - The whole world performance degrades with many ChronosManager
>> >> instances loaded? (Moving one around probably forces others to refresh
>> >> as well).
>> >>
>> >> What could be nice is to profile rendering time as well (but, if your
>> >> first render time is included in the 10% of 170ms you quote, then it is
>> >> probably fine).
>> >>
>> >> Would you like to try benchmarking rendering one ChronosManager instance
>> >> when you have 30 instances opened / only one instance opened?
>> >>
>> >> > So from the looks of it , it looks like Morphic does not perform well
>> >> > with loaded images and external files.
>> >>
>> >> This is a clear win if you cache those (i.e. have a LRU cache holding
>> >> forms and fonts, filled upon first load, reused over subsequent loads).
>> >>
>> >> Thierry
>> >>
>> >> >
>> >> >
>> >> > On Sun, Nov 22, 2015 at 11:34 AM Thierry Goubier
>> >> > <thierry.goubier(a)gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
>> >> >
>> >> > Hi all,
>> >> >
>> >> > I would like to ask you, all of you, something significant when doing
>> >> > GUI coding:
>> >> >
>> >> > Pay attention to performance!
>> >> >
>> >> > With the current state of our technology (Morphic, Bloc, whatever comes
>> >> > next) your target should be one hundred milliseconds (100 ms), for
>> >> > opening / redisplaying the widget.
>> >> >
>> >> > Why?
>> >> >
>> >> > - Because, in 10ms, Morphic can open and layout dozens of Morphs on a
>> >> > low-end machine (1.4GHz Celeron).
>> >> >
>> >> > - Because most of you work on 3GHz+ i7 Macbook Pro (so, at 10x the cpu
>> >> > performance of that said Celeron).
>> >> >
>> >> > - Because you are not to reproduce the past: that your current tools are
>> >> > slow is no excuse.
>> >> >
>> >> > - Because you now have well designed core widgets (FT) that behaves in
>> >> > O(1) and opens fully loaded in 10's of milliseconds
>> >> >
>> >> > So, profile and clean your code! Eliminate unneeded caches! Clean your
>> >> > architectures! Avoid or mark slow code and bottlenecks!
>> >> >
>> >> > And bring numbers when you want to criticize the performance of a
>> >> > subsystem...
>> >> >
>> >> > Thierry
>> >> >
>> >>
>> >>
>> >
>>
>> --
>> www.tudorgirba.com
>>
>> "Every now and then stop and ask yourself if the war you're fighting is the right one."
>>
>>
>>
>>
>
--
www.tudorgirba.com
"Presenting is storytelling."
Nov. 22, 2015