Iliad performance and improvements

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

Iliad performance and improvements

zecke-2
Hi,

I am currently writing/deploying a small configuration application for
an embedded ARM device (it doesn't get close to a smartphone... in
computing power) and showing the lightbox in the todolist example
takes close to three seconds. I have done some improvements/hacks in
GST but also changed some parts in Iliad.


1.) ILJson, String>>#printJsonOn:

 Iliad.ILJson class extend [
     printOrEscape: c to: stream [
        c == $" ifTrue: [^stream nextPut: $\; nextPut: $"].
        c == $\ ifTrue: [^stream nextPut: $\; nextPut: $\].
        c == $<8> ifTrue: [^stream nextPut: $\; nextPut: $b].
        c == $<9> ifTrue: [^stream nextPut: $\; nextPut: $t].
        c == $<10> ifTrue: [^stream nextPut: $\; nextPut: $n].
        c == $<12> ifTrue: [^stream nextPut: $\; nextPut: $f].
        c == $<13> ifTrue: [^stream nextPut: $\; nextPut: $r].
        stream nextPut: c.
     ]
 ]

 String extend [
    printJsonOn: aStream [
        <category: 'printing'>
        | replacement |
        aStream nextPut: $".
        self do: [:ch |
            Iliad.ILJson printOrEscape: ch to: aStream].
        aStream nextPut: $".
    ]
 ]
"

A simple "aString printJsonOn: stdout" test took about 1.8s before
with the above improvement it takes around 0.7s...





2.) ILElement use #>>nextPut: for a single character

Iliad.ILElement extend [
    printCloseTagOn: aStream [
        <category: 'printing'>
        self tag ifNotNil: [
                aStream
                    nextPutAll: '</';
                    nextPutAll: self tag;
                    nextPut: $> ]
    ]

    printOpenTagOn: aStream [
        <category: 'printing'>
        self tag ifNotNil: [
            aStream nextPut: $<; nextPutAll: self tag.
            self attributes associationsDo: [:each |
                each value ifNotNil: [
                    self printAttribute: each on: aStream]].
            aStream nextPut: $>]
    ]
 ]


3.) Use String>>new: to avoid growing the collection. For
ILScriptElement and such one could use >>#contents to reserve some
more.

Iliad.ILElement [
    printJsonOn: aStream [
        <category: 'printing'>
        | str |
        str := WriteStream on: (String new: 700).
        self printHtmlOn: str.
        str contents printJsonOn: aStream
    ]
]


4.) >>#== for the ILEncoder..

  Iliad.ILEncoder extend [
        encodeCharacterForHTTP: aCharacter on: aStream [
            <category: 'encoding'>
            aCharacter == $" ifTrue: [^aStream nextPutAll: '&quot;'].
            aCharacter == $< ifTrue: [^aStream nextPutAll: '&lt;'].
            aCharacter == $& ifTrue: [^aStream nextPutAll: '&amp;'].
            aCharacter == $> ifTrue: [^aStream nextPutAll: '&gt;'].
            aStream nextPut: aCharacter
        ]
  ]



I am now down to 700ms for showing the lightbox. gst-profile is still
showing the json encoding as a hot path and then
WriteStream>>#nextPut:. E.g. I wonder if you have considered allowing
a more tight integration between Iliad and Swazoo for response
handling? E.g. have the ILResponse directly stream to the Swazoo one?

Are you interested to merge any of the above changes?

kind regards
  holger


--
You received this message because you are subscribed to the Google Groups "Iliad project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: Iliad performance and improvements

Bernat Romagosa
Nice improvements! I'd be interested in having them merged, yes.

A tip Nicolas explained a couple weeks ago to get lightboxes to be rendered faster is to have them invoked from an empty widget, instead of the application or a data-filled widget. Otherwise, the caller widget gets re-rendered along with the lightbox. 

Something like:

YourApplication >> lightboxCaller
  ^ lightboxCaller ifNil: [ lightboxCaller := self widgetFor: [ :h | ] ]

YourApplication >> index
  ^ [ :h |
    "whatever you need to render"
    h build: self lightboxCaller ]

Since all my widgets inherit from an ILWidget subclass, I could overwrite #lightbox:onAnswer:, but you can also just send the message to self application lightboxCaller (although Demeter would frown).

MiWidgetSubclass >> lightbox: aWidget onAnswer: aBlock
  self application lightboxCaller lightbox: aWidget onAnswer: aBlock
 
I wrote this code from the tip of my head, it might not work exactly like this, but you get the idea!

Cheers,

Bernat.

2013/4/25 zecke <[hidden email]>
Hi,

I am currently writing/deploying a small configuration application for
an embedded ARM device (it doesn't get close to a smartphone... in
computing power) and showing the lightbox in the todolist example
takes close to three seconds. I have done some improvements/hacks in
GST but also changed some parts in Iliad.


1.) ILJson, String>>#printJsonOn:

 Iliad.ILJson class extend [
     printOrEscape: c to: stream [
        c == $" ifTrue: [^stream nextPut: $\; nextPut: $"].
        c == $\ ifTrue: [^stream nextPut: $\; nextPut: $\].
        c == $<8> ifTrue: [^stream nextPut: $\; nextPut: $b].
        c == $<9> ifTrue: [^stream nextPut: $\; nextPut: $t].
        c == $<10> ifTrue: [^stream nextPut: $\; nextPut: $n].
        c == $<12> ifTrue: [^stream nextPut: $\; nextPut: $f].
        c == $<13> ifTrue: [^stream nextPut: $\; nextPut: $r].
        stream nextPut: c.
     ]
 ]

 String extend [
    printJsonOn: aStream [
        <category: 'printing'>
        | replacement |
        aStream nextPut: $".
        self do: [:ch |
            Iliad.ILJson printOrEscape: ch to: aStream].
        aStream nextPut: $".
    ]
 ]
"

A simple "aString printJsonOn: stdout" test took about 1.8s before
with the above improvement it takes around 0.7s...





2.) ILElement use #>>nextPut: for a single character

Iliad.ILElement extend [
    printCloseTagOn: aStream [
        <category: 'printing'>
        self tag ifNotNil: [
                aStream
                    nextPutAll: '</';
                    nextPutAll: self tag;
                    nextPut: $> ]
    ]

    printOpenTagOn: aStream [
        <category: 'printing'>
        self tag ifNotNil: [
            aStream nextPut: $<; nextPutAll: self tag.
            self attributes associationsDo: [:each |
                each value ifNotNil: [
                    self printAttribute: each on: aStream]].
            aStream nextPut: $>]
    ]
 ]


3.) Use String>>new: to avoid growing the collection. For
ILScriptElement and such one could use >>#contents to reserve some
more.

Iliad.ILElement [
    printJsonOn: aStream [
        <category: 'printing'>
        | str |
        str := WriteStream on: (String new: 700).
        self printHtmlOn: str.
        str contents printJsonOn: aStream
    ]
]


4.) >>#== for the ILEncoder..

  Iliad.ILEncoder extend [
        encodeCharacterForHTTP: aCharacter on: aStream [
            <category: 'encoding'>
            aCharacter == $" ifTrue: [^aStream nextPutAll: '&quot;'].
            aCharacter == $< ifTrue: [^aStream nextPutAll: '&lt;'].
            aCharacter == $& ifTrue: [^aStream nextPutAll: '&amp;'].
            aCharacter == $> ifTrue: [^aStream nextPutAll: '&gt;'].
            aStream nextPut: aCharacter
        ]
  ]



I am now down to 700ms for showing the lightbox. gst-profile is still
showing the json encoding as a hot path and then
WriteStream>>#nextPut:. E.g. I wonder if you have considered allowing
a more tight integration between Iliad and Swazoo for response
handling? E.g. have the ILResponse directly stream to the Swazoo one?

Are you interested to merge any of the above changes?

kind regards
  holger


--
You received this message because you are subscribed to the Google Groups "Iliad project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.





--
Bernat Romagosa.

--
You received this message because you are subscribed to the Google Groups "Iliad project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply | Threaded
Open this post in threaded view
|

Re: Iliad performance and improvements

Paolo Bonzini-2
In reply to this post by zecke-2
Il 25/04/2013 21:59, zecke ha scritto:
>      printOrEscape: c to: stream [
> c == $" ifTrue: [^stream nextPut: $\; nextPut: $"].
> c == $\ ifTrue: [^stream nextPut: $\; nextPut: $\].

Perhaps here you can add a c codePoint <= 13 ifTrue: [ ... ]?

Paolo

> c == $<8> ifTrue: [^stream nextPut: $\; nextPut: $b].
> c == $<9> ifTrue: [^stream nextPut: $\; nextPut: $t].
>         c == $<10> ifTrue: [^stream nextPut: $\; nextPut: $n].
> c == $<12> ifTrue: [^stream nextPut: $\; nextPut: $f].
> c == $<13> ifTrue: [^stream nextPut: $\; nextPut: $r].
>         stream nextPut: c.
>      ]

--
You received this message because you are subscribed to the Google Groups "Iliad project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: Iliad performance and improvements

Paolo Bonzini-2
In reply to this post by zecke-2
Il 25/04/2013 21:59, zecke ha scritto:

> 2.) ILElement use #>>nextPut: for a single character
>
> Iliad.ILElement extend [
>     printCloseTagOn: aStream [
>         <category: 'printing'>
>         self tag ifNotNil: [
>                 aStream
>                     nextPutAll: '</';
>                     nextPutAll: self tag;
>                     nextPut: $> ]
>     ]

It's probably faster for two as well...

>
>
> Iliad.ILElement [
>     printJsonOn: aStream [
> <category: 'printing'>
> | str |
> str := WriteStream on: (String new: 700).
> self printHtmlOn: str.
> str contents printJsonOn: aStream
>     ]
> ]

Perhaps avoid the indirection altogether using a stream that does the
JSON encoding?

Paolo

--
You received this message because you are subscribed to the Google Groups "Iliad project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.