2015-12-08 6 views
7

Ho trovato quando ho un nuovo hash che ha sette oggetti è molto più lento di un hash di sei lunghezze. So che la durata dell'hash influirà sulle prestazioni. Ma non so perché sette è speciale.perché il nuovo hash che ha sette oggetti è molto più lento di un hash di sei lunghezze?

Ecco il codice di riferimento (Ruby 2.2.3):

require 'benchmark/ips' 

Benchmark.ips do |x| 
    x.report(5) { { a: 0, b: 1, c: 2, d: 3, e: 4 } } 
    x.report(6) { { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5 } } 
    x.report(7) { { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6 } } 
    x.report(8) { { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7 } } 
    x.report(9) { { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8 } } 

    x.compare! 
end 

E il colpo è il risultato:

Calculating ------------------------------------- 
        5 65.986k i/100ms 
        6 63.966k i/100ms 
        7 30.713k i/100ms 
        8 28.991k i/100ms 
        9 27.115k i/100ms 
------------------------------------------------- 
        5  1.243M (± 4.3%) i/s -  6.203M 
        6  1.202M (± 5.3%) i/s -  6.013M 
        7 373.366k (±13.7%) i/s -  1.843M 
        8 351.945k (± 8.8%) i/s -  1.768M 
        9 331.398k (± 8.2%) i/s -  1.654M 

Comparison: 
        5: 1243005.5 i/s 
        6: 1202032.4 i/s - 1.03x slower 
        7: 373366.5 i/s - 3.33x slower 
        8: 351945.1 i/s - 3.53x slower 
        9: 331398.3 i/s - 3.75x slower 
+0

Probabilmente correlato alla quantità di hash che si adatta in una singola riga della cache. Hai visto drop-off simili per hash più grandi? – chepner

risposta

5

Da Hash lookup in Ruby, why is it so fast?:

Rubino gestisce la dimensione della scomparti dinamicamente. Inizia con 11 e non appena uno dei bin contiene 5 o più elementi, la dimensione del cestino viene aumentata e tutti gli elementi hash vengono riallocati nel loro nuovo bin corrispondente.

Ad un certo punto si paga una penalità di tempo aumentata esponenzialmente mentre Ruby ridimensiona il pool di bin, ma se ci si pensa, vale la pena il tempo poiché ciò manterrà i tempi di ricerca e l'utilizzo della memoria il più basso possibile.

Ciò significa che più scomparti, meno tempo dedicato alla ricerca di una chiave specifica in un raccoglitore.

Spero che aiuti a capire il comportamento.

+2

Questa è una buona informazione, ma potresti citare un riferimento per questo? –

+0

@GregBurghardt: aggiornato con il riferimento –

+1

Grazie. Non lo sapevo su 'Hash's in Ruby. +1 –

Problemi correlati