Forum: Italian Ruby user group 100% cpu

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-02-23 09:39
ho un applicazione che improvvisamente inizia a richiedere risorse
infinite,
questo succede quando carico una view che deve mostrarmi un elenco di
eventi filtrati per data e posizionarli in una tabella ho un ciclo di
questo tipo:


result = %(<table>)
(9..19).each do |hour|
  result << %(<tr>)
   (0..6).each do |day|
     result << %(<td>#{ get_event(day, hour) }</td>)
   end
  result << %(</tr>)
end
result << %(</table>)

get_event prende i dati da una hash strutturata così:
eventi = { day_1 => { 9 => [events], 10 => [events], ....}, day_2 =>
.... }

qualche idea?
7de465f222e6a9c7fe658e370d0bfe05?d=identicon&s=25 Paolo Montrasio (pmontrasio)
on 2009-02-23 15:13
Ciao Alessandro,

mi verrebbe da chiedere: quanto è grande l'hash eventi e quanto sono
grandi i suoi valori? E' possibile che la to_s diventi impegnativa.
Bisognerebbe però lanciare un profiler per sapere dove passa il suo
tempo l'applicazione.

Paolo

Alessandro Scolavino wrote:
> ho un applicazione che improvvisamente inizia a richiedere risorse
> infinite,
> questo succede quando carico una view che deve mostrarmi un elenco di
> eventi filtrati per data e posizionarli in una tabella ho un ciclo di
> questo tipo:
>
>
> result = %(<table>)
> (9..19).each do |hour|
>   result << %(<tr>)
>    (0..6).each do |day|
>      result << %(<td>#{ get_event(day, hour) }</td>)
>    end
>   result << %(</tr>)
> end
> result << %(</table>)
>
> get_event prende i dati da una hash strutturata così:
> eventi = { day_1 => { 9 => [events], 10 => [events], ....}, day_2 =>
> .... }
>
> qualche idea?
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-02-24 18:07
Paolo Montrasio wrote:
> mi verrebbe da chiedere: quanto è grande l'hash eventi e quanto sono
> grandi i suoi valori?

L'hash contiene oggetti di tipo evento molto "piccoli" 4 campi di
tabellari (nome descrizione data utente id) ed è quasi sempre vuoto
durante i test per cui dovrebbe andare a razzo ...

> E' possibile che la to_s diventi impegnativa.
> Bisognerebbe però lanciare un profiler per sapere dove passa il suo
> tempo l'applicazione.

non avevo pensato al profiler, ora provo e vedo!
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-02 11:23
il problema è sulla string concatenation,

qualcuno ha idea su come velocizzarlo??

ho provato con :

pippo << "abcdef...."
pippo = pippo + "abcdef...."
pippo = "#{pippo}abcdef...."

stessi risultati... circa 10 secondi per 200 righe ...
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-02 11:41
Alessandro Scolavino wrote:
> il problema è sulla string concatenation,
>
> qualcuno ha idea su come velocizzarlo??
>
> ho provato con :
>
> pippo << "abcdef...."
> pippo = pippo + "abcdef...."
> pippo = "#{pippo}abcdef...."
>
> stessi risultati... circa 10 secondi per 200 righe ...



per chiarezza, il ciclo che sto usando è:

    first.upto(last) do |cur|
      cal << %(<td>#{button({ :nocenter => true, :class => "action
week_selector", :id => "week_View_#{cur.strftime("%W")}_#{cur.year}",
:alt => "#{_('Show Week')} #{cur.strftime("%W")}" })}</td>) if cur.wday
== first_weekday
      cell_text, cell_attrs = block.call(cur)
      cell_text  ||= cur.mday
      cell_attrs ||= {:class => options[:day_class]}
      cell_attrs[:class] += " weekendDay" if [0, 6].include?(cur.wday)
      cell_attrs[:class] += " today" if (cur == Date.today) and
options[:show_today]
      cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")
      cal << %(<td #{cell_attrs}><div class="app_day"><span
class="day_number">#{cur.day}</span><div class="calendar_cell
#{cur.strftime("%d_%m_%Y")}">
                #{ clerk_calendar.have_appo_day?(cur) ? %(<img
onclick="show_appo(this)" class="month_appo #{cur.strftime("%d_%m_%Y")}"
src="/images/icon/month_appo.png" />) : ""}
              </div></td>)
      cal << "</tr><tr>" if cur.wday == last_weekday
    end

fa parte di un plugin (ovviamente modificato per le mie esigenze), e
costruisce una vista mensile per un calendario.

Questo pezzo di codice ci mette circa 7 secondi (sono ben 30 cicli) il
tempo delle chiamate ai vari metodi è trascurabile (vicino a 0)
7daea92c28be2e85196a4f6dfdb2f689?d=identicon&s=25 Claudio Petasecca Donati (etapeta)
on 2009-03-02 12:21
Hai provato con la StringIO ?

result = StringIO.new
result << %(<table>)
(9..19).each do |hour|
   result << %(<tr>)
   (0..6).each do |day|
     result << %(<td>#{ get_event(day, hour) }</td>)
   end
  result << %(</tr>)
end
result << %(</table>)
result.rewind

<%= result.read %>
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-02 14:08
4 ore di prove e test e ho risolto, tutto dipendeva da strftime, per le
date non è performante conviene fare a mano ad
es.
"#{data.day}-#{data.month}-#{data.year}" vs data.strftime("%d-%m-%Y")
differenza quasi 0.2 secondi!!!
(il primo è istantaneo)

Si impara sempre qualcosa di nuovo!
7de465f222e6a9c7fe658e370d0bfe05?d=identicon&s=25 Paolo Montrasio (pmontrasio)
on 2009-03-03 19:23
Alessandro Scolavino wrote:
> 4 ore di prove e test e ho risolto, tutto dipendeva da strftime, per le
> date non è performante conviene fare a mano ad
> es.
> "#{data.day}-#{data.month}-#{data.year}" vs data.strftime("%d-%m-%Y")
> differenza quasi 0.2 secondi!!!
> (il primo è istantaneo)
>
> Si impara sempre qualcosa di nuovo!

Fantastico! Googlando dopo questa notizia ho trovato Date::Performance,
una gemma che riscrive l'implementazione della classe Date in C.

Documentazione: http://tomayko.com/src/date-performance/
Installazione: gem install date-performance --source=http://tomayko.com

Attenzione però che durante l'installazione dice

> WARNING:  RubyGems 1.2+ index not found for:
>  http://tomayko.com/

e fin qui tutto chiaro, e poi:

> RubyGems will revert to legacy indexes degrading performance.

il che è un po' preoccupante anche perché non ho trovato spiegazioni in
giro. Immagino però che le performance ridotte siano quelle di rubygems.

L'applicazione Rails su cui sto lavorando invece continua a funzionare
dopo la require 'date/performance' per cui tutto bene. Solo che non era
lenta prima e non pare più veloce adesso, anche se di strftime ne usa.

Se Alessandro avesse ancora a portata di mano il profiler forse potrebbe
dirci se questa nuova strftime è veloce quanto dice. Sarebbe meglio una
strftime veloce che la conversione manuale, no?

Paolo
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-03 19:35
Paolo Montrasio wrote:
> Alessandro Scolavino wrote:
>> 4 ore di prove e test e ho risolto, tutto dipendeva da strftime, per le
>> date non è performante conviene fare a mano ad
>> es.
>> "#{data.day}-#{data.month}-#{data.year}" vs data.strftime("%d-%m-%Y")
>> differenza quasi 0.2 secondi!!!
>> (il primo è istantaneo)
>>
>> Si impara sempre qualcosa di nuovo!
>
> Fantastico! Googlando dopo questa notizia ho trovato Date::Performance,
> una gemma che riscrive l'implementazione della classe Date in C.
>
> Documentazione: http://tomayko.com/src/date-performance/
> Installazione: gem install date-performance --source=http://tomayko.com
>
> Attenzione però che durante l'installazione dice
>
>> WARNING:  RubyGems 1.2+ index not found for:
>>  http://tomayko.com/
>
> e fin qui tutto chiaro, e poi:
>
>> RubyGems will revert to legacy indexes degrading performance.
>
> il che è un po' preoccupante anche perché non ho trovato spiegazioni in
> giro. Immagino però che le performance ridotte siano quelle di rubygems.
>
> L'applicazione Rails su cui sto lavorando invece continua a funzionare
> dopo la require 'date/performance' per cui tutto bene. Solo che non era
> lenta prima e non pare più veloce adesso, anche se di strftime ne usa.
>
> Se Alessandro avesse ancora a portata di mano il profiler forse potrebbe
> dirci se questa nuova strftime è veloce quanto dice. Sarebbe meglio una
> strftime veloce che la conversione manuale, no?
>
> Paolo

Bhe ho fatto un pò di test (un bel pò) non ho installato
date-performance (che avevo trovato anche io :P ) per quei messaggi
inquietanti...

Allora sulla classe Date passando da una chiamata strftime a una
"manuale" risparmio in media 1 decimo di secondo, se nel codice hai
poche chiamate non te ne accorgi, ma un ciclo come il mio che ne
eseguiva una 60-70ina inizia a diventare doloroso...

appena ho 1 oretta faccio una serie di test con profiler sulle 3 classi
e pubblico i risultati
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-05 15:33
Ho inserito i risultati del test sul mio blog:

http://www.webair.it/blog/2009/03/05/ruby-ancora-s...
7de465f222e6a9c7fe658e370d0bfe05?d=identicon&s=25 Paolo Montrasio (pmontrasio)
on 2009-03-05 16:52
Alessandro Scolavino wrote:
> Ho inserito i risultati del test sul mio blog:
>
> http://www.webair.it/blog/2009/03/05/ruby-ancora-s...

Ottimo lavoro. Ne ho approfittato per inserire come commento i risultati
dei benchmark con date-performance.

Riassunto: Date.strftime si velocizza di 60 volte. I dettagli sono sul
blog.
D716730ae3c9f3322f49d002192befc6?d=identicon&s=25 Alessandro Scolavino (ninjinka)
on 2009-03-05 22:25
Paolo Montrasio wrote:
> Alessandro Scolavino wrote:
>> Ho inserito i risultati del test sul mio blog:
>>
>> http://www.webair.it/blog/2009/03/05/ruby-ancora-s...
>
> Ottimo lavoro. Ne ho approfittato per inserire come commento i risultati
> dei benchmark con date-performance.
>
> Riassunto: Date.strftime si velocizza di 60 volte. I dettagli sono sul
> blog.

La installo subito!
(analizzando i benchmark ho notato che la lentezza di date deriva da un
sacco di chiamate alla classe String che come detto in precedenza è iper
lenta)
This topic is locked and can not be replied to.