A fast Transcript

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

A fast Transcript

Eliot Miranda-2
Hi Juan,

    I see that your new transcript is indeed much faster but is also not editable.  I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable.  For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to the standard fast output mode.  As you can infer I like having an editable transcript.  I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude editability.

On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <[hidden email]> wrote:
Hi Folks,

(below)


Quoting Ben Coman <[hidden email]>:

On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
wrote:



On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:

From my limited experience bug hunting, calling #changed: from a thread
other than the UI thread is a source of evil.  There are too many
assumptions throughout the system that the UI is single threaded.  Can
anyone advise me that is not a proper belief?

Then that implies that a Transcript implementation where #nextPut: direct
calls #changed:
is not appropriate for use with multi-threaded applications.  In Pharo,
#changed: is only called from #stepGlobal, which is called from
doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
release and maybe could use some cleanup.

Separating the UI from Transcript into its own viewer might be a good
idea, but actually it would not solve Stef's case since his code would
still be running in the UI thread -- unless the viewer ran in another
thread, which would have its own complexities.

I think the point about efficiency is significant. The following
example...
     Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
] ]
on Squeak 4.5 --> 12749ms
on Pharo 50029 --> 2ms

This better performance helped me a lot trying to understand the high
priority timerEventLoop being able to indiscriminately scatter Transcript
tracing through that code.  I believe its also probably beneficial for
working with externally triggered semaphores and timing sensitive race
conditions.

So we have two mutually exclusive cases:
* better interactivity, poorer system performance
* faster system performance, worse interactivity

Which of these is broken depends on your viewpoint.


Something that runs fast but is incorrect is still incorrect.  The fact
that the transcript doesn't output until a world step is possible is a
bug.  It forces programs that use the transcript to be rewritten in order
to see transcript output.


As a point of comparison for correctness, for the following...

    Transcript clear.
    [   $a asciiValue to: $z asciiValue do: [ :c |
  [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
printString , ' ' ] ] forkAt: 40
].
    ] forkAt: 41

Squeak 4.5 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4
$c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2
$i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7
$f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3
$v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4
$o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5
$m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6
$p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7
$l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8
$g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9
$f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9
$u9 $z9 $x9

Pharo 50041 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1
$c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2
$e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3
$g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4
$i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5
$k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6
$m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7
$o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8
$q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9
$t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1
$v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2
$x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3
$z4 $z5 $z6 $z7 $z8 $z9

(start your comparison at $b5)

So in one axis Pharo has improved Transcript, but we didn't notice the
significance of the use case we lost.

cheers -ben

Please take a good look at Cuis' Transcript and consider using it.

By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks:

        Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]. 763.

But if you want minimum overhead without immediate feedback:

        Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
        "As fast as Pharo"

It is also thread safe, and for Ben's example:

Transcript clear.
[
        $a asciiValue to: $z asciiValue do: [ :c |
                [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
        ].
] forkAt: 41

it gives the same result as Pharo.

The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate feedback. It has proved to be a useful aid in debugging Morphic code.

Cheers,
Juan Vuletich





--
best,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: A fast Transcript

J. Vuletich (mail lists)
Hi Eliot,

Yes, it is not editable. The approach you describe is a good idea.  
There are a few details to take care, like that the Cuis Transcript  
doesn't do wordwrap, and that's why it can work without the usual text  
editor machinery. So, maybe this editable Transcript should do no  
wordwrap, and have an horizontal scrollbar. Most likely there would be  
2 models, one like the one in Cuis, that is just a collection of  
lines, and another that is a regular text model. So those would need  
to be sync'ed, etc.

But it can be done and it would be great.

Cheers,
Juan Vuletich

Quoting Eliot Miranda <[hidden email]>:

> Hi Juan,
>
>     I see that your new transcript is indeed much faster but is also not
> editable.  I wonder if it would be possible to have the best of both worlds
> and arrange that, when active, the transcript is editable.  For example,
> selecting the TranscriptWIndow could put it into a mode where the
> transcript's state was imported into a more conventional editable text
> morph, and then when the window was exited, reverted to the standard fast
> output mode.  As you can infer I like having an editable transcript.  I can
> do without it, because Squeak's slow transcript is indeed a PITA, but I'm
> not sure that speed need preclude editability.
>
> On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <
> [hidden email]> wrote:
>
>> Hi Folks,
>>
>> (below)
>>
>>
>> Quoting Ben Coman <[hidden email]>:
>>
>>  On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
>>> wrote:
>>>
>>>
>>>>
>>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:
>>>>
>>>>  From my limited experience bug hunting, calling #changed: from a thread
>>>>> other than the UI thread is a source of evil.  There are too many
>>>>> assumptions throughout the system that the UI is single threaded.  Can
>>>>> anyone advise me that is not a proper belief?
>>>>>
>>>>> Then that implies that a Transcript implementation where #nextPut:
>>>>> direct
>>>>> calls #changed:
>>>>> is not appropriate for use with multi-threaded applications.  In Pharo,
>>>>> #changed: is only called from #stepGlobal, which is called from
>>>>> doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
>>>>> release and maybe could use some cleanup.
>>>>>
>>>>> Separating the UI from Transcript into its own viewer might be a good
>>>>> idea, but actually it would not solve Stef's case since his code would
>>>>> still be running in the UI thread -- unless the viewer ran in another
>>>>> thread, which would have its own complexities.
>>>>>
>>>>> I think the point about efficiency is significant. The following
>>>>> example...
>>>>>      Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
>>>>> ] ]
>>>>> on Squeak 4.5 --> 12749ms
>>>>> on Pharo 50029 --> 2ms
>>>>>
>>>>> This better performance helped me a lot trying to understand the high
>>>>> priority timerEventLoop being able to indiscriminately scatter
>>>>> Transcript
>>>>> tracing through that code.  I believe its also probably beneficial for
>>>>> working with externally triggered semaphores and timing sensitive race
>>>>> conditions.
>>>>>
>>>>> So we have two mutually exclusive cases:
>>>>> * better interactivity, poorer system performance
>>>>> * faster system performance, worse interactivity
>>>>>
>>>>> Which of these is broken depends on your viewpoint.
>>>>>
>>>>>
>>>> Something that runs fast but is incorrect is still incorrect.  The fact
>>>> that the transcript doesn't output until a world step is possible is a
>>>> bug.  It forces programs that use the transcript to be rewritten in order
>>>> to see transcript output.
>>>>
>>>>
>>> As a point of comparison for correctness, for the following...
>>>
>>>     Transcript clear.
>>>     [   $a asciiValue to: $z asciiValue do: [ :c |
>>>   [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
>>> printString , ' ' ] ] forkAt: 40
>>> ].
>>>     ] forkAt: 41
>>>
>>> Squeak 4.5 gives...
>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3
>>> $c4
>>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2
>>> $h2
>>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2
>>> $b7
>>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3
>>> $u3
>>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4
>>> $o4
>>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5
>>> $m5
>>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6
>>> $k6
>>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7
>>> $l7
>>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8
>>> $h8
>>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8
>>> $f9
>>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9
>>> $u9
>>> $u9 $z9 $x9
>>>
>>> Pharo 50041 gives...
>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9
>>> $c1
>>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1
>>> $e2
>>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2
>>> $g3
>>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3
>>> $i4
>>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4
>>> $k5
>>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5
>>> $m6
>>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6
>>> $o7
>>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7
>>> $q8
>>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8
>>> $s9
>>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9
>>> $v1
>>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1
>>> $x2
>>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2
>>> $z3
>>> $z4 $z5 $z6 $z7 $z8 $z9
>>>
>>> (start your comparison at $b5)
>>>
>>> So in one axis Pharo has improved Transcript, but we didn't notice the
>>> significance of the use case we lost.
>>>
>>> cheers -ben
>>>
>>
>> Please take a good look at Cuis' Transcript and consider using it.
>>
>> By default, the display is updated immediately, but without calling
>> Morphic, it can even work with no UI framework at all. It does updates
>> faster than Squeak or Visualworks:
>>
>>         Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show:
>> 'x' ] ]. 763.
>>
>> But if you want minimum overhead without immediate feedback:
>>
>>         Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000
>> timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
>>         "As fast as Pharo"
>>
>> It is also thread safe, and for Ben's example:
>>
>> Transcript clear.
>> [
>>         $a asciiValue to: $z asciiValue do: [ :c |
>>                 [ 1 to: 9 do: [ :i | Transcript show: c asCharacter
>> printString , i printString , ' ' ] ] forkAt: 40
>>         ].
>> ] forkAt: 41
>>
>> it gives the same result as Pharo.
>>
>> The fact that the updates are not bound to Morphic also means that it is
>> possible to do #show: deep in Morphic logic, without causing infinite loops
>> or recursions, and get immediate feedback. It has proved to be a useful aid
>> in debugging Morphic code.
>>
>> Cheers,
>> Juan Vuletich
>>
>>
>>
>
>
> --
> best,
> Eliot




Reply | Threaded
Open this post in threaded view
|

Re: A fast Transcript

Tudor Girba-2
In reply to this post by Eliot Miranda-2
Hi Eliot,

Just a question: Could you describe the situations when you need to have the Transcript editable?

I am not trying to provoke you, but to understand use cases. While working on GT I found that it is often possible to support the same use cases with multiple UI solutions. And sometimes considering alternatives leads to interesting results.

Cheers,
Doru



On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda <[hidden email]> wrote:
Hi Juan,

    I see that your new transcript is indeed much faster but is also not editable.  I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable.  For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to the standard fast output mode.  As you can infer I like having an editable transcript.  I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude editability.

On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <[hidden email]> wrote:
Hi Folks,

(below)


Quoting Ben Coman <[hidden email]>:

On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
wrote:



On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:

From my limited experience bug hunting, calling #changed: from a thread
other than the UI thread is a source of evil.  There are too many
assumptions throughout the system that the UI is single threaded.  Can
anyone advise me that is not a proper belief?

Then that implies that a Transcript implementation where #nextPut: direct
calls #changed:
is not appropriate for use with multi-threaded applications.  In Pharo,
#changed: is only called from #stepGlobal, which is called from
doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
release and maybe could use some cleanup.

Separating the UI from Transcript into its own viewer might be a good
idea, but actually it would not solve Stef's case since his code would
still be running in the UI thread -- unless the viewer ran in another
thread, which would have its own complexities.

I think the point about efficiency is significant. The following
example...
     Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
] ]
on Squeak 4.5 --> 12749ms
on Pharo 50029 --> 2ms

This better performance helped me a lot trying to understand the high
priority timerEventLoop being able to indiscriminately scatter Transcript
tracing through that code.  I believe its also probably beneficial for
working with externally triggered semaphores and timing sensitive race
conditions.

So we have two mutually exclusive cases:
* better interactivity, poorer system performance
* faster system performance, worse interactivity

Which of these is broken depends on your viewpoint.


Something that runs fast but is incorrect is still incorrect.  The fact
that the transcript doesn't output until a world step is possible is a
bug.  It forces programs that use the transcript to be rewritten in order
to see transcript output.


As a point of comparison for correctness, for the following...

    Transcript clear.
    [   $a asciiValue to: $z asciiValue do: [ :c |
  [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
printString , ' ' ] ] forkAt: 40
].
    ] forkAt: 41

Squeak 4.5 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4
$c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2
$i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7
$f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3
$v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4
$o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5
$m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6
$p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7
$l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8
$g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9
$f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9
$u9 $z9 $x9

Pharo 50041 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1
$c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2
$e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3
$g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4
$i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5
$k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6
$m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7
$o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8
$q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9
$t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1
$v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2
$x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3
$z4 $z5 $z6 $z7 $z8 $z9

(start your comparison at $b5)

So in one axis Pharo has improved Transcript, but we didn't notice the
significance of the use case we lost.

cheers -ben

Please take a good look at Cuis' Transcript and consider using it.

By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks:

        Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]. 763.

But if you want minimum overhead without immediate feedback:

        Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
        "As fast as Pharo"

It is also thread safe, and for Ben's example:

Transcript clear.
[
        $a asciiValue to: $z asciiValue do: [ :c |
                [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
        ].
] forkAt: 41

it gives the same result as Pharo.

The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate feedback. It has proved to be a useful aid in debugging Morphic code.

Cheers,
Juan Vuletich





--
best,
Eliot



--

"Every thing has its own flow"
Reply | Threaded
Open this post in threaded view
|

Re: A fast Transcript

Eliot Miranda-2
Hi Tudor,

On Sat, May 9, 2015 at 2:23 PM, Tudor Girba <[hidden email]> wrote:
Hi Eliot,

Just a question: Could you describe the situations when you need to have the Transcript editable?

I am not trying to provoke you,

my reputation preceeds me ;-)

 
but to understand use cases. While working on GT I found that it is often possible to support the same use cases with multiple UI solutions. And sometimes considering alternatives leads to interesting results.

While I have an over-full transcript that holds progress over time, notes etc, these could be moved to a workspace.  What I really use editablity in the transcript for is to cut-down output.  For example, if I'm analysing some jitted code it will get printed out in the transcript (without a lot of retooling) and it is very convenient to cut down the often large amount of output to focus on what I'm interested in.  Or I might be trying to fix a bug with repeated runs and again collect relevant data (print outs of objects or stack frames from the simulator) for use as reference points in later runs.  Or I might collect some warnings from the Slang SMalltalk-to-C translator.

In short, there's a lot of different kinds of data going to the transcript and it can be useful to edit it in place instead of having to copy it elsewhere.


Cheers,
Doru



On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda <[hidden email]> wrote:
Hi Juan,

    I see that your new transcript is indeed much faster but is also not editable.  I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable.  For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to the standard fast output mode.  As you can infer I like having an editable transcript.  I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude editability.

On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <[hidden email]> wrote:
Hi Folks,

(below)


Quoting Ben Coman <[hidden email]>:

On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
wrote:



On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:

From my limited experience bug hunting, calling #changed: from a thread
other than the UI thread is a source of evil.  There are too many
assumptions throughout the system that the UI is single threaded.  Can
anyone advise me that is not a proper belief?

Then that implies that a Transcript implementation where #nextPut: direct
calls #changed:
is not appropriate for use with multi-threaded applications.  In Pharo,
#changed: is only called from #stepGlobal, which is called from
doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
release and maybe could use some cleanup.

Separating the UI from Transcript into its own viewer might be a good
idea, but actually it would not solve Stef's case since his code would
still be running in the UI thread -- unless the viewer ran in another
thread, which would have its own complexities.

I think the point about efficiency is significant. The following
example...
     Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
] ]
on Squeak 4.5 --> 12749ms
on Pharo 50029 --> 2ms

This better performance helped me a lot trying to understand the high
priority timerEventLoop being able to indiscriminately scatter Transcript
tracing through that code.  I believe its also probably beneficial for
working with externally triggered semaphores and timing sensitive race
conditions.

So we have two mutually exclusive cases:
* better interactivity, poorer system performance
* faster system performance, worse interactivity

Which of these is broken depends on your viewpoint.


Something that runs fast but is incorrect is still incorrect.  The fact
that the transcript doesn't output until a world step is possible is a
bug.  It forces programs that use the transcript to be rewritten in order
to see transcript output.


As a point of comparison for correctness, for the following...

    Transcript clear.
    [   $a asciiValue to: $z asciiValue do: [ :c |
  [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
printString , ' ' ] ] forkAt: 40
].
    ] forkAt: 41

Squeak 4.5 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4
$c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2
$i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7
$f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3
$v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4
$o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5
$m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6
$p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7
$l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8
$g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9
$f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9
$u9 $z9 $x9

Pharo 50041 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1
$c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2
$e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3
$g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4
$i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5
$k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6
$m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7
$o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8
$q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9
$t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1
$v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2
$x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3
$z4 $z5 $z6 $z7 $z8 $z9

(start your comparison at $b5)

So in one axis Pharo has improved Transcript, but we didn't notice the
significance of the use case we lost.

cheers -ben

Please take a good look at Cuis' Transcript and consider using it.

By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks:

        Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]. 763.

But if you want minimum overhead without immediate feedback:

        Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
        "As fast as Pharo"

It is also thread safe, and for Ben's example:

Transcript clear.
[
        $a asciiValue to: $z asciiValue do: [ :c |
                [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
        ].
] forkAt: 41

it gives the same result as Pharo.

The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate feedback. It has proved to be a useful aid in debugging Morphic code.

Cheers,
Juan Vuletich





--
best,
Eliot



--

"Every thing has its own flow"



--
best,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: A fast Transcript

Levente Uzonyi-2
On Sun, 10 May 2015, karl ramberg wrote:

> If you disable preference 'Force Transcrip updates to screen' you will get much higher performance.Redrawing is then minimal
> Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'] ] 694

Right, but then it won't update the contents of the morph, while your code
is running in the UI process. So you have to fork your process, just like
in Pharo.

Levente

>
> Karl
>
> On Sun, May 10, 2015 at 4:01 AM, Eliot Miranda <[hidden email]> wrote:
>       Hi Tudor,
>
>       On Sat, May 9, 2015 at 2:23 PM, Tudor Girba <[hidden email]> wrote:
>             Hi Eliot,
> Just a question: Could you describe the situations when you need to have the Transcript editable?
>
> I am not trying to provoke you,
>
>
> my reputation preceeds me ;-)
>
>  
>       but to understand use cases. While working on GT I found that it is often possible to support the same use cases with multiple UI solutions. And sometimes considering alternatives leads to
>       interesting results.
>
>
> While I have an over-full transcript that holds progress over time, notes etc, these could be moved to a workspace.  What I really use editablity in the transcript for is to cut-down output.  For
> example, if I'm analysing some jitted code it will get printed out in the transcript (without a lot of retooling) and it is very convenient to cut down the often large amount of output to focus on what
> I'm interested in.  Or I might be trying to fix a bug with repeated runs and again collect relevant data (print outs of objects or stack frames from the simulator) for use as reference points in later
> runs.  Or I might collect some warnings from the Slang SMalltalk-to-C translator.
>
> In short, there's a lot of different kinds of data going to the transcript and it can be useful to edit it in place instead of having to copy it elsewhere.
>
>
> Cheers,
> Doru
>
>
>
> On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda <[hidden email]> wrote:
>       Hi Juan,
>     I see that your new transcript is indeed much faster but is also not editable.  I wonder if it would be possible to have the best of both worlds and arrange that, when active, the
> transcript is editable.  For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then
> when the window was exited, reverted to the standard fast output mode.  As you can infer I like having an editable transcript.  I can do without it, because Squeak's slow transcript is
> indeed a PITA, but I'm not sure that speed need preclude editability.
>
> On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <[hidden email]> wrote:
>       Hi Folks,
>
>       (below)
>
>       Quoting Ben Coman <[hidden email]>:
>
>             On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
>             wrote:
>
>
>
>                   On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:
>
>                         >From my limited experience bug hunting, calling #changed: from a thread
>                         other than the UI thread is a source of evil.  There are too many
>                         assumptions throughout the system that the UI is single threaded.  Can
>                         anyone advise me that is not a proper belief?
>
>                         Then that implies that a Transcript implementation where #nextPut: direct
>                         calls #changed:
>                         is not appropriate for use with multi-threaded applications.  In Pharo,
>                         #changed: is only called from #stepGlobal, which is called from
>                         doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
>                         release and maybe could use some cleanup.
>
>                         Separating the UI from Transcript into its own viewer might be a good
>                         idea, but actually it would not solve Stef's case since his code would
>                         still be running in the UI thread -- unless the viewer ran in another
>                         thread, which would have its own complexities.
>
>                         I think the point about efficiency is significant. The following
>                         example...
>                              Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
>                         ] ]
>                         on Squeak 4.5 --> 12749ms
>                         on Pharo 50029 --> 2ms
>
>                         This better performance helped me a lot trying to understand the high
>                         priority timerEventLoop being able to indiscriminately scatter Transcript
>                         tracing through that code.  I believe its also probably beneficial for
>                         working with externally triggered semaphores and timing sensitive race
>                         conditions.
>
>                         So we have two mutually exclusive cases:
>                         * better interactivity, poorer system performance
>                         * faster system performance, worse interactivity
>
>                         Which of these is broken depends on your viewpoint.
>
>
>                   Something that runs fast but is incorrect is still incorrect.  The fact
>                   that the transcript doesn't output until a world step is possible is a
>                   bug.  It forces programs that use the transcript to be rewritten in order
>                   to see transcript output.
>
>
>             As a point of comparison for correctness, for the following...
>
>                 Transcript clear.
>                 [   $a asciiValue to: $z asciiValue do: [ :c |
>               [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
>             printString , ' ' ] ] forkAt: 40
>             ].
>                 ] forkAt: 41
>
>             Squeak 4.5 gives...
>             $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4
>             $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2
>             $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7
>             $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3
>             $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4
>             $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5
>             $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6
>             $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7
>             $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8
>             $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9
>             $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9
>             $u9 $z9 $x9
>
>             Pharo 50041 gives...
>             $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1
>             $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2
>             $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3
>             $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4
>             $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5
>             $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6
>             $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7
>             $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8
>             $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9
>             $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1
>             $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2
>             $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3
>             $z4 $z5 $z6 $z7 $z8 $z9
>
>             (start your comparison at $b5)
>
>             So in one axis Pharo has improved Transcript, but we didn't notice the
>             significance of the use case we lost.
>
>             cheers -ben
>
>
> Please take a good look at Cuis' Transcript and consider using it.
>
> By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks:
>
>         Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]. 763.
>
> But if you want minimum overhead without immediate feedback:
>
>         Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
>         "As fast as Pharo"
>
> It is also thread safe, and for Ben's example:
>
> Transcript clear.
> [
>         $a asciiValue to: $z asciiValue do: [ :c |
>                 [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
>         ].
> ] forkAt: 41
>
> it gives the same result as Pharo.
>
> The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate
> feedback. It has proved to be a useful aid in debugging Morphic code.
>
> Cheers,
> Juan Vuletich
>
>
>
>
>
> --
> best,Eliot
>
>
>
>
> --
> www.tudorgirba.com
>
> "Every thing has its own flow"
>
>
>
>
> --
> best,Eliot
>
>
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: A fast Transcript

J. Vuletich (mail lists)
In reply to this post by Eliot Miranda-2
Hi Eliot,

Today I woke up with a simple idea: In Cuis' Transcript, once you do  
"Workspace with contents", keep a reference to that workspace, and add  
new Transcript stuff to it. This is done afterwards, when Morphic runs  
again. Immediate Transcript update is not affected. The effect is like  
having an editable Transcript, with a fast, immediate "preview" in a  
separate window.

I just did a commit to the Cuis Github repo with this (amongst a lot  
of other changes). Please try it and tell if this simple solution is  
enough for your needs.

OT: BTW, I added a new VMMaker package. It is a verbatim copy of the  
latest VMMaker in http://source.squeak.org/VMMaker/ . I didn't change  
a single line of code (except for one method in GeniePlugin that seems  
to break some compiler limit). It can generate all the plugins. This  
is all I tested so far. The GUI is not functional, due to the  
differences in Morphic. But at least there are no Undeclared.

Cheers,
Juan Vuletich

www.cuis-smalltalk.org
https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev


Quoting Eliot Miranda <[hidden email]>:

> Hi Juan,
>
>     I see that your new transcript is indeed much faster but is also not
> editable.  I wonder if it would be possible to have the best of both worlds
> and arrange that, when active, the transcript is editable.  For example,
> selecting the TranscriptWIndow could put it into a mode where the
> transcript's state was imported into a more conventional editable text
> morph, and then when the window was exited, reverted to the standard fast
> output mode.  As you can infer I like having an editable transcript.  I can
> do without it, because Squeak's slow transcript is indeed a PITA, but I'm
> not sure that speed need preclude editability.
>
> On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <
> [hidden email]> wrote:
>
>> Hi Folks,
>>
>> (below)
>>
>>
>> Quoting Ben Coman <[hidden email]>:
>>
>>  On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
>>> wrote:
>>>
>>>
>>>>
>>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:
>>>>
>>>>  From my limited experience bug hunting, calling #changed: from a thread
>>>>> other than the UI thread is a source of evil.  There are too many
>>>>> assumptions throughout the system that the UI is single threaded.  Can
>>>>> anyone advise me that is not a proper belief?
>>>>>
>>>>> Then that implies that a Transcript implementation where #nextPut:
>>>>> direct
>>>>> calls #changed:
>>>>> is not appropriate for use with multi-threaded applications.  In Pharo,
>>>>> #changed: is only called from #stepGlobal, which is called from
>>>>> doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
>>>>> release and maybe could use some cleanup.
>>>>>
>>>>> Separating the UI from Transcript into its own viewer might be a good
>>>>> idea, but actually it would not solve Stef's case since his code would
>>>>> still be running in the UI thread -- unless the viewer ran in another
>>>>> thread, which would have its own complexities.
>>>>>
>>>>> I think the point about efficiency is significant. The following
>>>>> example...
>>>>>      Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
>>>>> ] ]
>>>>> on Squeak 4.5 --> 12749ms
>>>>> on Pharo 50029 --> 2ms
>>>>>
>>>>> This better performance helped me a lot trying to understand the high
>>>>> priority timerEventLoop being able to indiscriminately scatter
>>>>> Transcript
>>>>> tracing through that code.  I believe its also probably beneficial for
>>>>> working with externally triggered semaphores and timing sensitive race
>>>>> conditions.
>>>>>
>>>>> So we have two mutually exclusive cases:
>>>>> * better interactivity, poorer system performance
>>>>> * faster system performance, worse interactivity
>>>>>
>>>>> Which of these is broken depends on your viewpoint.
>>>>>
>>>>>
>>>> Something that runs fast but is incorrect is still incorrect.  The fact
>>>> that the transcript doesn't output until a world step is possible is a
>>>> bug.  It forces programs that use the transcript to be rewritten in order
>>>> to see transcript output.
>>>>
>>>>
>>> As a point of comparison for correctness, for the following...
>>>
>>>     Transcript clear.
>>>     [   $a asciiValue to: $z asciiValue do: [ :c |
>>>   [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
>>> printString , ' ' ] ] forkAt: 40
>>> ].
>>>     ] forkAt: 41
>>>
>>> Squeak 4.5 gives...
>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3
>>> $c4
>>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2
>>> $h2
>>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2
>>> $b7
>>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3
>>> $u3
>>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4
>>> $o4
>>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5
>>> $m5
>>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6
>>> $k6
>>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7
>>> $l7
>>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8
>>> $h8
>>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8
>>> $f9
>>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9
>>> $u9
>>> $u9 $z9 $x9
>>>
>>> Pharo 50041 gives...
>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9
>>> $c1
>>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1
>>> $e2
>>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2
>>> $g3
>>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3
>>> $i4
>>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4
>>> $k5
>>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5
>>> $m6
>>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6
>>> $o7
>>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7
>>> $q8
>>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8
>>> $s9
>>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9
>>> $v1
>>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1
>>> $x2
>>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2
>>> $z3
>>> $z4 $z5 $z6 $z7 $z8 $z9
>>>
>>> (start your comparison at $b5)
>>>
>>> So in one axis Pharo has improved Transcript, but we didn't notice the
>>> significance of the use case we lost.
>>>
>>> cheers -ben
>>>
>>
>> Please take a good look at Cuis' Transcript and consider using it.
>>
>> By default, the display is updated immediately, but without calling
>> Morphic, it can even work with no UI framework at all. It does updates
>> faster than Squeak or Visualworks:
>>
>>         Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show:
>> 'x' ] ]. 763.
>>
>> But if you want minimum overhead without immediate feedback:
>>
>>         Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000
>> timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
>>         "As fast as Pharo"
>>
>> It is also thread safe, and for Ben's example:
>>
>> Transcript clear.
>> [
>>         $a asciiValue to: $z asciiValue do: [ :c |
>>                 [ 1 to: 9 do: [ :i | Transcript show: c asCharacter
>> printString , i printString , ' ' ] ] forkAt: 40
>>         ].
>> ] forkAt: 41
>>
>> it gives the same result as Pharo.
>>
>> The fact that the updates are not bound to Morphic also means that it is
>> possible to do #show: deep in Morphic logic, without causing infinite loops
>> or recursions, and get immediate feedback. It has proved to be a useful aid
>> in debugging Morphic code.
>>
>> Cheers,
>> Juan Vuletich
>>
>>
>>
>
>
> --
> best,
> Eliot



Reply | Threaded
Open this post in threaded view
|

Re: A fast Transcript

Tudor Girba-2
In reply to this post by Eliot Miranda-2
Hi,

On Sun, May 10, 2015 at 4:01 AM, Eliot Miranda <[hidden email]> wrote:
Hi Tudor,

On Sat, May 9, 2015 at 2:23 PM, Tudor Girba <[hidden email]> wrote:
Hi Eliot,

Just a question: Could you describe the situations when you need to have the Transcript editable?

I am not trying to provoke you,

my reputation preceeds me ;-)

:)

 
 
but to understand use cases. While working on GT I found that it is often possible to support the same use cases with multiple UI solutions. And sometimes considering alternatives leads to interesting results.

While I have an over-full transcript that holds progress over time, notes etc, these could be moved to a workspace.  What I really use editablity in the transcript for is to cut-down output.  For example, if I'm analysing some jitted code it will get printed out in the transcript (without a lot of retooling) and it is very convenient to cut down the often large amount of output to focus on what I'm interested in.  Or I might be trying to fix a bug with repeated runs and again collect relevant data (print outs of objects or stack frames from the simulator) for use as reference points in later runs.  Or I might collect some warnings from the Slang SMalltalk-to-C translator.

In short, there's a lot of different kinds of data going to the transcript and it can be useful to edit it in place instead of having to copy it elsewhere.

Interesting. While I see how text editing can be used for these use cases, I also think that there might be other options. For example, for cutting output it would be enough to have something working on the rendering level only (like collapsing lines) without impacting the content.

Cheers,
Doru

 

Cheers,
Doru



On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda <[hidden email]> wrote:
Hi Juan,

    I see that your new transcript is indeed much faster but is also not editable.  I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable.  For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to the standard fast output mode.  As you can infer I like having an editable transcript.  I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude editability.

On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) <[hidden email]> wrote:
Hi Folks,

(below)


Quoting Ben Coman <[hidden email]>:

On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <[hidden email]>
wrote:



On Sat, May 9, 2015 at 7:09 AM, Ben Coman <[hidden email]> wrote:

From my limited experience bug hunting, calling #changed: from a thread
other than the UI thread is a source of evil.  There are too many
assumptions throughout the system that the UI is single threaded.  Can
anyone advise me that is not a proper belief?

Then that implies that a Transcript implementation where #nextPut: direct
calls #changed:
is not appropriate for use with multi-threaded applications.  In Pharo,
#changed: is only called from #stepGlobal, which is called from
doOneCycle:.  (This came about as a last minute bug fix before Pharo 3
release and maybe could use some cleanup.

Separating the UI from Transcript into its own viewer might be a good
idea, but actually it would not solve Stef's case since his code would
still be running in the UI thread -- unless the viewer ran in another
thread, which would have its own complexities.

I think the point about efficiency is significant. The following
example...
     Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x'
] ]
on Squeak 4.5 --> 12749ms
on Pharo 50029 --> 2ms

This better performance helped me a lot trying to understand the high
priority timerEventLoop being able to indiscriminately scatter Transcript
tracing through that code.  I believe its also probably beneficial for
working with externally triggered semaphores and timing sensitive race
conditions.

So we have two mutually exclusive cases:
* better interactivity, poorer system performance
* faster system performance, worse interactivity

Which of these is broken depends on your viewpoint.


Something that runs fast but is incorrect is still incorrect.  The fact
that the transcript doesn't output until a world step is possible is a
bug.  It forces programs that use the transcript to be rewritten in order
to see transcript output.


As a point of comparison for correctness, for the following...

    Transcript clear.
    [   $a asciiValue to: $z asciiValue do: [ :c |
  [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i
printString , ' ' ] ] forkAt: 40
].
    ] forkAt: 41

Squeak 4.5 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4
$c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2
$i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7
$f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3
$v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4
$o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5
$m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6
$p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7
$l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8
$g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9
$f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9
$u9 $z9 $x9

Pharo 50041 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1
$c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2
$e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3
$g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4
$i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5
$k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6
$m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7
$o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8
$q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9
$t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1
$v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2
$x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3
$z4 $z5 $z6 $z7 $z8 $z9

(start your comparison at $b5)

So in one axis Pharo has improved Transcript, but we didn't notice the
significance of the use case we lost.

cheers -ben

Please take a good look at Cuis' Transcript and consider using it.

By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks:

        Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]. 763.

But if you want minimum overhead without immediate feedback:

        Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:  [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1.
        "As fast as Pharo"

It is also thread safe, and for Ben's example:

Transcript clear.
[
        $a asciiValue to: $z asciiValue do: [ :c |
                [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
        ].
] forkAt: 41

it gives the same result as Pharo.

The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate feedback. It has proved to be a useful aid in debugging Morphic code.

Cheers,
Juan Vuletich





--
best,
Eliot



--

"Every thing has its own flow"



--
best,
Eliot



--

"Every thing has its own flow"