Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- 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
- 1 participants
- 144621 messages
Re: [Pharo-project] [squeak-dev] Re: Optimizing RunArray
by Nicolas Cellier
One thing that super upset me is that TextEditor is still using the
old selectors #readKeyboard #keyboard #keyboardPeek instead of using
events.
Look #handleInteraction:fromEvent:
It still has this hackish code to transform event driven Morph into
st-80-polling-ParagraphEditor-friendly-Sensor-like
self editor sensor: (KeyboardBuffer new startingEvent: evt).
IMO,
self handleInteraction: [ editor readKeyboard ] fromEvent: evt.
should be replaced with
self handleInteraction: [ editor keyStroke: evt ].
and the hack should be delegated to the TextMorphEditor (ParagraphEditor)
keyStrocke: anEvent
"Pass the event to a polling friendly sensor like so that old st-80
code shall still work"
self sensor: (KeyboardBuffer new startingEvent: evt).
self readKeyboard.
Then TextEditor>>keyStrocke: should dispatchKeyboardEvent: anEvent
with: typeAhead and stop querying a pseudo sensor.
Of course, that means changing a lot of methods in TextEditor (any
method with 'sensor' in source).
But if TextEditor is just a place holder for copying the st-80
ParagraphEditor code and the early Morphic hacks, I just don't see the
point of making such a copy ;)
Nicolas
2011/8/2 Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>:
> I have tried again with huge text (my 45 MByte change log).
> Main contributor seems to be Text composition.
> A marginal gain (2 to 3% when resizing the window) is to remove the
> indirection in TextStopConditions, and replace instance variable stops
> with direct integer slots (variableSubclass)
>
> No guaranty the fileIn of attachment will work, modifying Text
> processing is dangerous...
>
> Nicolas
>
> 2011/8/2 Stéphane Ducasse <stephane.ducasse(a)inria.fr>:
>> Yes I was wondering about the same (for athens too :))
>>
>> Stef
>>
>> On Aug 2, 2011, at 2:16 PM, Igor Stasenko wrote:
>>
>>> Does it impacts the text rendering/processing speed?
>>>
>>>
>>> On 2 August 2011 12:11, Nicolas Cellier
>>> <nicolas.cellier.aka.nice(a)gmail.com> wrote:
>>>> To complete myself, the fast #collect: already exists and is named
>>>> #mapValues: except that it modifies the RunArray in place and also
>>>> won't coalesce...
>>>>
>>>> I also gain a huge factor for #collect:as: be defining this method:
>>>>
>>>> RunArray>>fillFrom: aCollection with: aBlock
>>>> Â Â Â Â "Evaluate aBlock with each of aCollections's elements as the argument.
>>>> Â Â Â Â Collect the resulting values into self. Answer self."
>>>> Â Â Â Â | newRuns newValues lastLength lastValue |
>>>> Â Â Â Â newRuns := (Array new: aCollection size) writeStream.
>>>> Â Â Â Â newValues := (Array new: aCollection size) writeStream.
>>>> Â Â Â Â lastLength := 0.
>>>> Â Â Â Â lastValue := Object new.
>>>> Â Â Â Â aCollection do: [:each |
>>>> Â Â Â Â Â Â Â Â | value |
>>>> Â Â Â Â Â Â Â Â value := aBlock value: each.
>>>> Â Â Â Â Â Â Â Â lastValue = value
>>>> Â Â Â Â Â Â Â Â Â Â Â Â ifTrue: [lastLength := lastLength + 1]
>>>> Â Â Â Â Â Â Â Â Â Â Â Â ifFalse:
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [lastLength > 0
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ifTrue:
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [newRuns nextPut: lastLength.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â newValues nextPut: lastValue].
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â lastLength := 1.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â lastValue := value]].
>>>> Â Â Â Â lastLength > 0
>>>> Â Â Â Â Â Â Â Â ifTrue:
>>>> Â Â Â Â Â Â Â Â Â Â Â Â [newRuns nextPut: lastLength.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â newValues nextPut: lastValue].
>>>> Â Â Â Â self setRuns: newRuns contents setValues: newValues contents
>>>>
>>>> [ (Array new: 1000) collect: [:e | 4 atRandom] as: RunArray] bench.
>>>> BEFORE: '25.1 per second.'
>>>> AFTER: Â '1,080 per second.'
>>>>
>>>> It's worth a few lines of code.
>>>>
>>>> Nicolas
>>>>
>>>> 2011/8/2 Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>:
>>>>> I played a bit with RunArray, and found some un-optimized features.
>>>>> First, I don't know why RunArray is an ArrayedCollection. It cannot
>>>>> #add: but it can #addFirst: and #addLast:.
>>>>> It cannot #add:withOccurrences: but it can #addLast:times:. Why
>>>>> inventing new selectors for old behaviours ?
>>>>> These operations will cost a realloc it the last value is different,
>>>>> so the underlying runs/values could better be an OrderedCollection if
>>>>> these operations are used often.
>>>>> A RunArray cannot remove at all.
>>>>> Very weird collection species, I don't like the implementation too much.
>>>>>
>>>>> Then, #do: loops could be far faster. They rely on ArrayedCollection
>>>>> which inlines do: loops with #to:do: and #at:
>>>>> But #at: is not that fast. Scanning the runs and counting elements
>>>>> would result in a n^2 cost.
>>>>> Fortunately there is a cache lastIndex,lastRun,lastOffset to keep a cost n.
>>>>> Nonetheless, all the tests cost, and the loop is suboptimal.
>>>>> Let use see:
>>>>>
>>>>> version 1:
>>>>> RunArray>>fastDo: aBlock
>>>>> Â Â Â Â runs with: values do: [:r :v |
>>>>> Â Â Â Â Â Â Â Â r timesRepeat: [aBlock value: v]].
>>>>>
>>>>> | tmp |
>>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>>> {
>>>>> [ tmp do: [:e |]] bench.
>>>>> [ tmp fastDo: [:e |]] bench.
>>>>> }
>>>>> #('3,220 per second.' '6,290 per second.')
>>>>>
>>>>> But timesRepeat: is slow, it is unoptimized by the compiler and costs
>>>>> a message send.
>>>>> I think we should implement BlockClosure>>repeat: and optimize that
>>>>> call in Compiler.
>>>>> But let's not do it, and rather inline by ourself:
>>>>>
>>>>> version 2:
>>>>> Â Â Â Â runs with: values do: [:r :v |
>>>>> Â Â Â Â Â Â Â Â 1 to: r do: [:i | aBlock value: v]].
>>>>>
>>>>> | tmp |
>>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>>> {
>>>>> [ tmp do: [:e |]] bench.
>>>>> [ tmp do2: [:e |]] bench.
>>>>> }
>>>>> #('3,070 per second.' '25,500 per second.')
>>>>>
>>>>> We can even inline the with:do: loop itself:
>>>>> version 3:
>>>>> Â Â Â Â 1 to: runs size do: [:i |
>>>>> Â Â Â Â Â Â Â Â | r v |
>>>>> Â Â Â Â Â Â Â Â v := values at: i.
>>>>> Â Â Â Â Â Â Â Â r := runs at: i.
>>>>> Â Â Â Â Â Â Â Â [( r := r - 1) >= 0]
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â whileTrue: [aBlock value: v]].
>>>>>
>>>>> | tmp |
>>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>>> {
>>>>> [ tmp do: [:e |]] bench.
>>>>> [ tmp do2: [:e |]] bench.
>>>>> }
>>>>> #('3,370 per second.' '32,200 per second.')
>>>>>
>>>>> Now the operation I wanted to use was reverseDo: so I implemented:
>>>>> RunArray>>fastReverseDo: aBlock
>>>>> Â Â Â Â | i |
>>>>> Â Â Â Â i := runs size.
>>>>> Â Â Â Â [i > 0]
>>>>> Â Â Â Â Â Â Â Â whileTrue:
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â [ | r v |
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â v := values at: i.
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â r := runs at: i.
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â i := i - 1.
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â [( r := r - 1) >= 0]
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â whileTrue: [aBlock value: v]].
>>>>> | tmp |
>>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>>> {
>>>>> [ tmp reverseDo: [:e |]] bench.
>>>>> [ tmp reverseDo2: [:e |]] bench.
>>>>> }
>>>>> Â #('83.9 per second.' '32,600 per second.')
>>>>>
>>>>> Ouch! The cache is missing a lot of indices, and our loop turns into a n^2 cost.
>>>>> I know, premature optimization bla bla bla, but a factor x400 is worth
>>>>> some inlining no?
>>>>>
>>>>> I guess these features are never used.
>>>>> By now RunArray is kind of private utility for Text implementation.
>>>>> But it could / should be generic.
>>>>>
>>>>> I also have proposals for count: / select: / collect:. etc...
>>>>> It would be to evaluate the block only once per group of values.
>>>>> For example
>>>>> RunArray>>collect: aBlock
>>>>> Â Â Â Â "Beware, the block will be evaluated only once per group of values."
>>>>> Â Â Â Â ^(self class runs: (runs collect: aBlock) contents values: values
>>>>> copy) coalesce
>>>>> But that's controversial, it would make the RunArray behave
>>>>> differently if the block has side effects...
>>>>>
>>>>> | i tmp tmp2 tmp3 |
>>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]).
>>>>> i := 0.
>>>>> tmp2 := tmp collect: [:e | i := i + 1].
>>>>> i := 0.
>>>>> tmp3 := (tmp as: RunArray) collect: [:e | i := i + 1].
>>>>> tmp2 = tmp3 asArray
>>>>> ==> false
>>>>>
>>>>> Nicolas
>>>>>
>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Best regards,
>>> Igor Stasenko AKA sig.
>>>
>>
>>
>>
>
Aug. 2, 2011
Re: [Pharo-project] building from PharoKernel
by laurent laffont
Is it actually possible to load ConfigurationOfSeaside30 in PharoKernel ?
I've tried using
https://ci.lille.inria.fr/pharo/job/Pharo%20Kernel%20Gofer/6/artifact/Pharo…
it seems to do nothing...
Note that builds #7 and #8 .zip seem to contain a PharoCore and not
PharoKernel.
Laurent
On Tue, Aug 2, 2011 at 11:08 PM, Pavel Krivanek <pavel.krivanek(a)gmail.com>wrote:
> We still do not have MinimalMorphic image equivalent so there is no
> reason to use it for DrGeo. However you may try to create DrGeo image,
> then start with Gefer image, load all methods that are not present in
> the Gofer image in form of a proxy method that will log the method
> call, loads the right code and executes it. Some supporting code is on
> the wiki of http://www.squeaksource.com/KernelImage.html.
> MinimalMorphic was created partly using this way.
>
> -- Pavel
>
> On Tue, Aug 2, 2011 at 3:41 PM, Hilaire Fernandes
> <hilaire.fernandes(a)edu.ge.ch> wrote:
> > I would like to build a DrGeo image from PharoKernel. Is it something
> > possible? I guess I am not the only one wondering about that
> >
> > Hilaire
> >
> >
> > --
> > Education 0.2 -- http://blog.ofset.org/hilaire
> >
> >
> >
>
>
Aug. 2, 2011
Re: [Pharo-project] [squeak-dev] Re: Optimizing RunArray
by Nicolas Cellier
I have tried again with huge text (my 45 MByte change log).
Main contributor seems to be Text composition.
A marginal gain (2 to 3% when resizing the window) is to remove the
indirection in TextStopConditions, and replace instance variable stops
with direct integer slots (variableSubclass)
No guaranty the fileIn of attachment will work, modifying Text
processing is dangerous...
Nicolas
2011/8/2 Stéphane Ducasse <stephane.ducasse(a)inria.fr>:
> Yes I was wondering about the same (for athens too :))
>
> Stef
>
> On Aug 2, 2011, at 2:16 PM, Igor Stasenko wrote:
>
>> Does it impacts the text rendering/processing speed?
>>
>>
>> On 2 August 2011 12:11, Nicolas Cellier
>> <nicolas.cellier.aka.nice(a)gmail.com> wrote:
>>> To complete myself, the fast #collect: already exists and is named
>>> #mapValues: except that it modifies the RunArray in place and also
>>> won't coalesce...
>>>
>>> I also gain a huge factor for #collect:as: be defining this method:
>>>
>>> RunArray>>fillFrom: aCollection with: aBlock
>>> Â Â Â Â "Evaluate aBlock with each of aCollections's elements as the argument.
>>> Â Â Â Â Collect the resulting values into self. Answer self."
>>> Â Â Â Â | newRuns newValues lastLength lastValue |
>>> Â Â Â Â newRuns := (Array new: aCollection size) writeStream.
>>> Â Â Â Â newValues := (Array new: aCollection size) writeStream.
>>> Â Â Â Â lastLength := 0.
>>> Â Â Â Â lastValue := Object new.
>>> Â Â Â Â aCollection do: [:each |
>>> Â Â Â Â Â Â Â Â | value |
>>> Â Â Â Â Â Â Â Â value := aBlock value: each.
>>> Â Â Â Â Â Â Â Â lastValue = value
>>> Â Â Â Â Â Â Â Â Â Â Â Â ifTrue: [lastLength := lastLength + 1]
>>> Â Â Â Â Â Â Â Â Â Â Â Â ifFalse:
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [lastLength > 0
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ifTrue:
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [newRuns nextPut: lastLength.
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â newValues nextPut: lastValue].
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â lastLength := 1.
>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â lastValue := value]].
>>> Â Â Â Â lastLength > 0
>>> Â Â Â Â Â Â Â Â ifTrue:
>>> Â Â Â Â Â Â Â Â Â Â Â Â [newRuns nextPut: lastLength.
>>> Â Â Â Â Â Â Â Â Â Â Â Â newValues nextPut: lastValue].
>>> Â Â Â Â self setRuns: newRuns contents setValues: newValues contents
>>>
>>> [ (Array new: 1000) collect: [:e | 4 atRandom] as: RunArray] bench.
>>> BEFORE: '25.1 per second.'
>>> AFTER: Â '1,080 per second.'
>>>
>>> It's worth a few lines of code.
>>>
>>> Nicolas
>>>
>>> 2011/8/2 Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>:
>>>> I played a bit with RunArray, and found some un-optimized features.
>>>> First, I don't know why RunArray is an ArrayedCollection. It cannot
>>>> #add: but it can #addFirst: and #addLast:.
>>>> It cannot #add:withOccurrences: but it can #addLast:times:. Why
>>>> inventing new selectors for old behaviours ?
>>>> These operations will cost a realloc it the last value is different,
>>>> so the underlying runs/values could better be an OrderedCollection if
>>>> these operations are used often.
>>>> A RunArray cannot remove at all.
>>>> Very weird collection species, I don't like the implementation too much.
>>>>
>>>> Then, #do: loops could be far faster. They rely on ArrayedCollection
>>>> which inlines do: loops with #to:do: and #at:
>>>> But #at: is not that fast. Scanning the runs and counting elements
>>>> would result in a n^2 cost.
>>>> Fortunately there is a cache lastIndex,lastRun,lastOffset to keep a cost n.
>>>> Nonetheless, all the tests cost, and the loop is suboptimal.
>>>> Let use see:
>>>>
>>>> version 1:
>>>> RunArray>>fastDo: aBlock
>>>> Â Â Â Â runs with: values do: [:r :v |
>>>> Â Â Â Â Â Â Â Â r timesRepeat: [aBlock value: v]].
>>>>
>>>> | tmp |
>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>> {
>>>> [ tmp do: [:e |]] bench.
>>>> [ tmp fastDo: [:e |]] bench.
>>>> }
>>>> #('3,220 per second.' '6,290 per second.')
>>>>
>>>> But timesRepeat: is slow, it is unoptimized by the compiler and costs
>>>> a message send.
>>>> I think we should implement BlockClosure>>repeat: and optimize that
>>>> call in Compiler.
>>>> But let's not do it, and rather inline by ourself:
>>>>
>>>> version 2:
>>>> Â Â Â Â runs with: values do: [:r :v |
>>>> Â Â Â Â Â Â Â Â 1 to: r do: [:i | aBlock value: v]].
>>>>
>>>> | tmp |
>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>> {
>>>> [ tmp do: [:e |]] bench.
>>>> [ tmp do2: [:e |]] bench.
>>>> }
>>>> #('3,070 per second.' '25,500 per second.')
>>>>
>>>> We can even inline the with:do: loop itself:
>>>> version 3:
>>>> Â Â Â Â 1 to: runs size do: [:i |
>>>> Â Â Â Â Â Â Â Â | r v |
>>>> Â Â Â Â Â Â Â Â v := values at: i.
>>>> Â Â Â Â Â Â Â Â r := runs at: i.
>>>> Â Â Â Â Â Â Â Â [( r := r - 1) >= 0]
>>>> Â Â Â Â Â Â Â Â Â Â Â Â whileTrue: [aBlock value: v]].
>>>>
>>>> | tmp |
>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>> {
>>>> [ tmp do: [:e |]] bench.
>>>> [ tmp do2: [:e |]] bench.
>>>> }
>>>> #('3,370 per second.' '32,200 per second.')
>>>>
>>>> Now the operation I wanted to use was reverseDo: so I implemented:
>>>> RunArray>>fastReverseDo: aBlock
>>>> Â Â Â Â | i |
>>>> Â Â Â Â i := runs size.
>>>> Â Â Â Â [i > 0]
>>>> Â Â Â Â Â Â Â Â whileTrue:
>>>> Â Â Â Â Â Â Â Â Â Â Â Â [ | r v |
>>>> Â Â Â Â Â Â Â Â Â Â Â Â v := values at: i.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â r := runs at: i.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â i := i - 1.
>>>> Â Â Â Â Â Â Â Â Â Â Â Â [( r := r - 1) >= 0]
>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â whileTrue: [aBlock value: v]].
>>>> | tmp |
>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>>> {
>>>> [ tmp reverseDo: [:e |]] bench.
>>>> [ tmp reverseDo2: [:e |]] bench.
>>>> }
>>>> Â #('83.9 per second.' '32,600 per second.')
>>>>
>>>> Ouch! The cache is missing a lot of indices, and our loop turns into a n^2 cost.
>>>> I know, premature optimization bla bla bla, but a factor x400 is worth
>>>> some inlining no?
>>>>
>>>> I guess these features are never used.
>>>> By now RunArray is kind of private utility for Text implementation.
>>>> But it could / should be generic.
>>>>
>>>> I also have proposals for count: / select: / collect:. etc...
>>>> It would be to evaluate the block only once per group of values.
>>>> For example
>>>> RunArray>>collect: aBlock
>>>> Â Â Â Â "Beware, the block will be evaluated only once per group of values."
>>>> Â Â Â Â ^(self class runs: (runs collect: aBlock) contents values: values
>>>> copy) coalesce
>>>> But that's controversial, it would make the RunArray behave
>>>> differently if the block has side effects...
>>>>
>>>> | i tmp tmp2 tmp3 |
>>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]).
>>>> i := 0.
>>>> tmp2 := tmp collect: [:e | i := i + 1].
>>>> i := 0.
>>>> tmp3 := (tmp as: RunArray) collect: [:e | i := i + 1].
>>>> tmp2 = tmp3 asArray
>>>> ==> false
>>>>
>>>> Nicolas
>>>>
>>>
>>>
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>
>
>
Aug. 2, 2011
Re: [Pharo-project] building from PharoKernel
by Pavel Krivanek
We still do not have MinimalMorphic image equivalent so there is no
reason to use it for DrGeo. However you may try to create DrGeo image,
then start with Gefer image, load all methods that are not present in
the Gofer image in form of a proxy method that will log the method
call, loads the right code and executes it. Some supporting code is on
the wiki of http://www.squeaksource.com/KernelImage.html.
MinimalMorphic was created partly using this way.
-- Pavel
On Tue, Aug 2, 2011 at 3:41 PM, Hilaire Fernandes
<hilaire.fernandes(a)edu.ge.ch> wrote:
> I would like to build a DrGeo image from PharoKernel. Is it something
> possible? I guess I am not the only one wondering about that
>
> Hilaire
>
>
> --
> Education 0.2 -- http://blog.ofset.org/hilaire
>
>
>
Aug. 2, 2011
[Pharo-project] [update 1.4] #14072
by Stéphane Ducasse
14072
-----
- Issue 3433: Color improvement
http://code.google.com/p/pharo/issues/detail?id=3433
- Better class comment for FlatListMessageBrowser
Aug. 2, 2011
Re: [Pharo-project] [squeak-dev] Re: Optimizing RunArray
by Stéphane Ducasse
Yes I was wondering about the same (for athens too :))
Stef
On Aug 2, 2011, at 2:16 PM, Igor Stasenko wrote:
> Does it impacts the text rendering/processing speed?
>
>
> On 2 August 2011 12:11, Nicolas Cellier
> <nicolas.cellier.aka.nice(a)gmail.com> wrote:
>> To complete myself, the fast #collect: already exists and is named
>> #mapValues: except that it modifies the RunArray in place and also
>> won't coalesce...
>>
>> I also gain a huge factor for #collect:as: be defining this method:
>>
>> RunArray>>fillFrom: aCollection with: aBlock
>> "Evaluate aBlock with each of aCollections's elements as the argument.
>> Collect the resulting values into self. Answer self."
>> | newRuns newValues lastLength lastValue |
>> newRuns := (Array new: aCollection size) writeStream.
>> newValues := (Array new: aCollection size) writeStream.
>> lastLength := 0.
>> lastValue := Object new.
>> aCollection do: [:each |
>> | value |
>> value := aBlock value: each.
>> lastValue = value
>> ifTrue: [lastLength := lastLength + 1]
>> ifFalse:
>> [lastLength > 0
>> ifTrue:
>> [newRuns nextPut: lastLength.
>> newValues nextPut: lastValue].
>> lastLength := 1.
>> lastValue := value]].
>> lastLength > 0
>> ifTrue:
>> [newRuns nextPut: lastLength.
>> newValues nextPut: lastValue].
>> self setRuns: newRuns contents setValues: newValues contents
>>
>> [ (Array new: 1000) collect: [:e | 4 atRandom] as: RunArray] bench.
>> BEFORE: '25.1 per second.'
>> AFTER: '1,080 per second.'
>>
>> It's worth a few lines of code.
>>
>> Nicolas
>>
>> 2011/8/2 Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>:
>>> I played a bit with RunArray, and found some un-optimized features.
>>> First, I don't know why RunArray is an ArrayedCollection. It cannot
>>> #add: but it can #addFirst: and #addLast:.
>>> It cannot #add:withOccurrences: but it can #addLast:times:. Why
>>> inventing new selectors for old behaviours ?
>>> These operations will cost a realloc it the last value is different,
>>> so the underlying runs/values could better be an OrderedCollection if
>>> these operations are used often.
>>> A RunArray cannot remove at all.
>>> Very weird collection species, I don't like the implementation too much.
>>>
>>> Then, #do: loops could be far faster. They rely on ArrayedCollection
>>> which inlines do: loops with #to:do: and #at:
>>> But #at: is not that fast. Scanning the runs and counting elements
>>> would result in a n^2 cost.
>>> Fortunately there is a cache lastIndex,lastRun,lastOffset to keep a cost n.
>>> Nonetheless, all the tests cost, and the loop is suboptimal.
>>> Let use see:
>>>
>>> version 1:
>>> RunArray>>fastDo: aBlock
>>> runs with: values do: [:r :v |
>>> r timesRepeat: [aBlock value: v]].
>>>
>>> | tmp |
>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>> {
>>> [ tmp do: [:e |]] bench.
>>> [ tmp fastDo: [:e |]] bench.
>>> }
>>> #('3,220 per second.' '6,290 per second.')
>>>
>>> But timesRepeat: is slow, it is unoptimized by the compiler and costs
>>> a message send.
>>> I think we should implement BlockClosure>>repeat: and optimize that
>>> call in Compiler.
>>> But let's not do it, and rather inline by ourself:
>>>
>>> version 2:
>>> runs with: values do: [:r :v |
>>> 1 to: r do: [:i | aBlock value: v]].
>>>
>>> | tmp |
>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>> {
>>> [ tmp do: [:e |]] bench.
>>> [ tmp do2: [:e |]] bench.
>>> }
>>> #('3,070 per second.' '25,500 per second.')
>>>
>>> We can even inline the with:do: loop itself:
>>> version 3:
>>> 1 to: runs size do: [:i |
>>> | r v |
>>> v := values at: i.
>>> r := runs at: i.
>>> [( r := r - 1) >= 0]
>>> whileTrue: [aBlock value: v]].
>>>
>>> | tmp |
>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>> {
>>> [ tmp do: [:e |]] bench.
>>> [ tmp do2: [:e |]] bench.
>>> }
>>> #('3,370 per second.' '32,200 per second.')
>>>
>>> Now the operation I wanted to use was reverseDo: so I implemented:
>>> RunArray>>fastReverseDo: aBlock
>>> | i |
>>> i := runs size.
>>> [i > 0]
>>> whileTrue:
>>> [ | r v |
>>> v := values at: i.
>>> r := runs at: i.
>>> i := i - 1.
>>> [( r := r - 1) >= 0]
>>> whileTrue: [aBlock value: v]].
>>> | tmp |
>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>>> {
>>> [ tmp reverseDo: [:e |]] bench.
>>> [ tmp reverseDo2: [:e |]] bench.
>>> }
>>> #('83.9 per second.' '32,600 per second.')
>>>
>>> Ouch! The cache is missing a lot of indices, and our loop turns into a n^2 cost.
>>> I know, premature optimization bla bla bla, but a factor x400 is worth
>>> some inlining no?
>>>
>>> I guess these features are never used.
>>> By now RunArray is kind of private utility for Text implementation.
>>> But it could / should be generic.
>>>
>>> I also have proposals for count: / select: / collect:. etc...
>>> It would be to evaluate the block only once per group of values.
>>> For example
>>> RunArray>>collect: aBlock
>>> "Beware, the block will be evaluated only once per group of values."
>>> ^(self class runs: (runs collect: aBlock) contents values: values
>>> copy) coalesce
>>> But that's controversial, it would make the RunArray behave
>>> differently if the block has side effects...
>>>
>>> | i tmp tmp2 tmp3 |
>>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]).
>>> i := 0.
>>> tmp2 := tmp collect: [:e | i := i + 1].
>>> i := 0.
>>> tmp3 := (tmp as: RunArray) collect: [:e | i := i + 1].
>>> tmp2 = tmp3 asArray
>>> ==> false
>>>
>>> Nicolas
>>>
>>
>>
>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
Aug. 2, 2011
Re: [Pharo-project] Optimizing RunArray
by Stéphane Ducasse
Excellent!
Stef
On Aug 2, 2011, at 12:11 PM, Nicolas Cellier wrote:
> To complete myself, the fast #collect: already exists and is named
> #mapValues: except that it modifies the RunArray in place and also
> won't coalesce...
>
> I also gain a huge factor for #collect:as: be defining this method:
>
> RunArray>>fillFrom: aCollection with: aBlock
> "Evaluate aBlock with each of aCollections's elements as the argument.
> Collect the resulting values into self. Answer self."
> | newRuns newValues lastLength lastValue |
> newRuns := (Array new: aCollection size) writeStream.
> newValues := (Array new: aCollection size) writeStream.
> lastLength := 0.
> lastValue := Object new.
> aCollection do: [:each |
> | value |
> value := aBlock value: each.
> lastValue = value
> ifTrue: [lastLength := lastLength + 1]
> ifFalse:
> [lastLength > 0
> ifTrue:
> [newRuns nextPut: lastLength.
> newValues nextPut: lastValue].
> lastLength := 1.
> lastValue := value]].
> lastLength > 0
> ifTrue:
> [newRuns nextPut: lastLength.
> newValues nextPut: lastValue].
> self setRuns: newRuns contents setValues: newValues contents
>
> [ (Array new: 1000) collect: [:e | 4 atRandom] as: RunArray] bench.
> BEFORE: '25.1 per second.'
> AFTER: '1,080 per second.'
>
> It's worth a few lines of code.
>
> Nicolas
>
> 2011/8/2 Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>:
>> I played a bit with RunArray, and found some un-optimized features.
>> First, I don't know why RunArray is an ArrayedCollection. It cannot
>> #add: but it can #addFirst: and #addLast:.
>> It cannot #add:withOccurrences: but it can #addLast:times:. Why
>> inventing new selectors for old behaviours ?
>> These operations will cost a realloc it the last value is different,
>> so the underlying runs/values could better be an OrderedCollection if
>> these operations are used often.
>> A RunArray cannot remove at all.
>> Very weird collection species, I don't like the implementation too much.
>>
>> Then, #do: loops could be far faster. They rely on ArrayedCollection
>> which inlines do: loops with #to:do: and #at:
>> But #at: is not that fast. Scanning the runs and counting elements
>> would result in a n^2 cost.
>> Fortunately there is a cache lastIndex,lastRun,lastOffset to keep a cost n.
>> Nonetheless, all the tests cost, and the loop is suboptimal.
>> Let use see:
>>
>> version 1:
>> RunArray>>fastDo: aBlock
>> runs with: values do: [:r :v |
>> r timesRepeat: [aBlock value: v]].
>>
>> | tmp |
>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>> {
>> [ tmp do: [:e |]] bench.
>> [ tmp fastDo: [:e |]] bench.
>> }
>> #('3,220 per second.' '6,290 per second.')
>>
>> But timesRepeat: is slow, it is unoptimized by the compiler and costs
>> a message send.
>> I think we should implement BlockClosure>>repeat: and optimize that
>> call in Compiler.
>> But let's not do it, and rather inline by ourself:
>>
>> version 2:
>> runs with: values do: [:r :v |
>> 1 to: r do: [:i | aBlock value: v]].
>>
>> | tmp |
>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>> {
>> [ tmp do: [:e |]] bench.
>> [ tmp do2: [:e |]] bench.
>> }
>> #('3,070 per second.' '25,500 per second.')
>>
>> We can even inline the with:do: loop itself:
>> version 3:
>> 1 to: runs size do: [:i |
>> | r v |
>> v := values at: i.
>> r := runs at: i.
>> [( r := r - 1) >= 0]
>> whileTrue: [aBlock value: v]].
>>
>> | tmp |
>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>> {
>> [ tmp do: [:e |]] bench.
>> [ tmp do2: [:e |]] bench.
>> }
>> #('3,370 per second.' '32,200 per second.')
>>
>> Now the operation I wanted to use was reverseDo: so I implemented:
>> RunArray>>fastReverseDo: aBlock
>> | i |
>> i := runs size.
>> [i > 0]
>> whileTrue:
>> [ | r v |
>> v := values at: i.
>> r := runs at: i.
>> i := i - 1.
>> [( r := r - 1) >= 0]
>> whileTrue: [aBlock value: v]].
>> | tmp |
>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]) as: RunArray.
>> {
>> [ tmp reverseDo: [:e |]] bench.
>> [ tmp reverseDo2: [:e |]] bench.
>> }
>> #('83.9 per second.' '32,600 per second.')
>>
>> Ouch! The cache is missing a lot of indices, and our loop turns into a n^2 cost.
>> I know, premature optimization bla bla bla, but a factor x400 is worth
>> some inlining no?
>>
>> I guess these features are never used.
>> By now RunArray is kind of private utility for Text implementation.
>> But it could / should be generic.
>>
>> I also have proposals for count: / select: / collect:. etc...
>> It would be to evaluate the block only once per group of values.
>> For example
>> RunArray>>collect: aBlock
>> "Beware, the block will be evaluated only once per group of values."
>> ^(self class runs: (runs collect: aBlock) contents values: values
>> copy) coalesce
>> But that's controversial, it would make the RunArray behave
>> differently if the block has side effects...
>>
>> | i tmp tmp2 tmp3 |
>> tmp := ((Array new: 1000) collect: [:e | 4 atRandom]).
>> i := 0.
>> tmp2 := tmp collect: [:e | i := i + 1].
>> i := 0.
>> tmp3 := (tmp as: RunArray) collect: [:e | i := i + 1].
>> tmp2 = tmp3 asArray
>> ==> false
>>
>> Nicolas
>>
>
Aug. 2, 2011
Re: [Pharo-project] Disable the debugger
by Stéphane Ducasse
would be nice to have a class responsible for that and that slowly we get a complete system ready for this kind of deployement
Stef
On Aug 2, 2011, at 7:06 PM, Mariano Martinez Peck wrote:
> Check in older Pharo images like 1.1.1 all the stuff in #disableProgrammerFacilities
>
>
> disableProgrammerFacilities
> "Warning: do not call this lightly! It disables all access to menus, debuggers, halos. There is no guaranteed return from this, which is to say, you cannot necessarily reenable these things once they are disabled -- you can only use whatever the UI of the current project affords, and you cannot even snapshot -- you can only quit.
>
> You can completely reverse the work of this method by calling the dual Preferences method enableProgrammerFacilities, provided you have left yourself leeway to bring about a call to that method.
> (does not reverse the ToolSet registrations)
>
> To set up a system that will come up in such a state, you have to request the snapshot in the same breath as you disable the programmer facilities. To do this, put the following line into the 'do' menu and then evaluate it from that 'do' menu:
>
> Preferences disableProgrammerFacilities.
>
> You will be prompted for a new image name under which to save the resulting image."
> self deprecated: 'No replacement for now'.
>
> Beeper beep.
> (self
> confirm: 'CAUTION!!
> This is a drastic step!
> Do you really want to do this?')
> ifFalse:
> [Beeper beep.
> ^self inform: 'whew!'].
> self disable: #cmdDotEnabled. "No user-interrupt-into-debugger"
> self disable: #editableStringMorphs. "turn off shift-click editing"
> ToolSet registeredClasses copy do: [:c | ToolSet unregister: c].
> ToolSet default: nil. "unregister and make sure default is nil to really prevent debug windows"
> "also now takes care of low space watcher interrupts"
> self compileHardCodedPref: #cmdGesturesEnabled enable: false. "No halos, etc."
> self compileHardCodedPref: #cmdKeysInText enable: false. "No user commands invokable via cmd-key combos in text editor"
> self enable: #noviceMode. "No control-menu"
> self disable: #warnIfNoSourcesFile.
> self disable: #warnIfNoChangesFile.
> Smalltalk saveAs
>
> On Tue, Aug 2, 2011 at 5:59 PM, laurent laffont <laurent.laffont(a)gmail.com> wrote:
> Hi,
>
> is it possible to disable the debugger in a Seaside image for production ?
>
> Laurent Laffont - @lolgzs
>
> Pharo Smalltalk Screencasts: http://www.pharocasts.com/
> Blog: http://magaloma.blogspot.com/
> Developer group: http://cara74.seasidehosting.st
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
Aug. 2, 2011
Re: [Pharo-project] Polymorph improvements
by Stéphane Ducasse
thanks for sharing that with us.
BTW did you see my question (some weeks ago) about minimalExtent or maximalExtent for window
it seems that it is totally unused.
Stef
> Screenshot of part of project: http://www.flickr.com/photos/12018791@N06/6001799235/in/photostream
>
> Regards, Gary
> ----- Original Message -----
> From: Gary Chambers
> To: Pharo Development
> Sent: Tuesday, August 02, 2011 4:40 PM
> Subject: [Pharo-project] Polymorph improvements
>
> Hi all.
>
> I've added an issue with some tweaks/improvements to a few Polymorph classes.
>
> http://code.google.com/p/pharo/issues/detail?id=4590
>
> Groupboxes can now have dynamic content (model/getContentSelector based).
> Abaility to create icon lists via builder/TEasilyThemed.
> Expander labels now LabelMorphs rather than TextMorphs (can therefore appear as disabled)
> IncrementalSliderMorphs now honour minWidth/minHeight in layouts
> Panel morphs allow event based mouse over handling (call to super was missing).
> Label groups allow for nil labels (equates to empty string)
>
> Regards, Gary
Aug. 2, 2011
Re: [Pharo-project] identityHash bits not incremented for new objects?
by Stéphane Ducasse
+ 10000000
>>>>>>>
>>
>
> Please include a comment with that. :)
> Like this has shown, it's rather hard to know wtf to do when you can't unambiguously read what its actually intended to test from the code itself.
>
> Cheers,
> Henry
>
>
Aug. 2, 2011