यह हमेशा विभिन्न सुझाए गए उत्तरों पर एक बेंचमार्क करने के लिए ज्ञानवर्धक है। यहाँ मुझे पता चला है:
#! / Usr / bin / माणिक
'बेंचमार्क' की आवश्यकता
ऐरी = []
1000. शर्तें {
ऐरी << {: बार => रैंड (1000)}
}
n = 500
बेंचमार्क.बीएम (20) करना | x |
x.report ("सॉर्ट") {n.times {ary.sort {| a, b | b [: बार] <=> ए [: बार]}}}
x.report ("सॉर्ट रिवर्स") {n.times {ary.sort {| a, b | [a: बार] <=> b [: bar]} .reverse}}
x.report ("Sort_by -a [: bar]") {n.times {ary.sort_by {| a | -एक बार] } } }
x.report ("Sort_by a [: bar] * - 1") {n.times {ary.s.s_by {{a | [[: बार] * - १}}}
x.report ("Sort_by.reverse!") {n.times {ary.sort_by {| a [[: बार]} .reverse}}
समाप्त
उपयोगकर्ता प्रणाली कुल वास्तविक
सॉर्ट 3.960000 0.010000 3.970000 (3.990886)
सॉर्ट रिवर्स 4.040000 0.000000 4.040000 (4.038849)
Sort_by -a [: बार] 0.690000 0.000000 0.690000 (0.692080)
Sort_by एक [: बार] * - 1 0.700000 0.000000 0.700000 (0.699735)
sort_by.reverse! 0.650000 0.000000 0.650000 (0.654447)
मुझे लगता है कि यह दिलचस्प है कि @ पाब्लो sort_by{...}.reverse!
सबसे तेज है। परीक्षण चलाने से पहले मैंने सोचा था कि यह " -a[:bar]
" की तुलना में धीमा होगा, लेकिन मूल्य को नकारने से अधिक समय लगता है जब यह एक सरणी में पूरे सरणी को उलट देता है। यह बहुत अंतर नहीं है, लेकिन हर छोटी गति में मदद करता है।
कृपया ध्यान दें कि ये परिणाम रूबी 1.9 में भिन्न हैं
यहाँ रूबी 1.9.3p194 (2012-04-20 संशोधन 35410) के परिणाम हैं [x86_64-darwin10.8.0]:
user system total real
sort 1.340000 0.010000 1.350000 ( 1.346331)
sort reverse 1.300000 0.000000 1.300000 ( 1.310446)
sort_by -a[:bar] 0.430000 0.000000 0.430000 ( 0.429606)
sort_by a[:bar]*-1 0.420000 0.000000 0.420000 ( 0.414383)
sort_by.reverse! 0.400000 0.000000 0.400000 ( 0.401275)
ये एक पुराने मैकबुक प्रो पर हैं। नई या तेज मशीनों में कम मूल्य होंगे, लेकिन सापेक्ष अंतर बने रहेंगे।
यहाँ नए हार्डवेयर पर थोड़ा अद्यतन संस्करण और रूबी का 2.1.1 संस्करण है:
#!/usr/bin/ruby
require 'benchmark'
puts "Running Ruby #{RUBY_VERSION}"
ary = []
1000.times {
ary << {:bar => rand(1000)}
}
n = 500
puts "n=#{n}"
Benchmark.bm(20) do |x|
x.report("sort") { n.times { ary.dup.sort{ |a,b| b[:bar] <=> a[:bar] } } }
x.report("sort reverse") { n.times { ary.dup.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
x.report("sort_by -a[:bar]") { n.times { ary.dup.sort_by{ |a| -a[:bar] } } }
x.report("sort_by a[:bar]*-1") { n.times { ary.dup.sort_by{ |a| a[:bar]*-1 } } }
x.report("sort_by.reverse") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse } }
x.report("sort_by.reverse!") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse! } }
end
# >> Running Ruby 2.1.1
# >> n=500
# >> user system total real
# >> sort 0.670000 0.000000 0.670000 ( 0.667754)
# >> sort reverse 0.650000 0.000000 0.650000 ( 0.655582)
# >> sort_by -a[:bar] 0.260000 0.010000 0.270000 ( 0.255919)
# >> sort_by a[:bar]*-1 0.250000 0.000000 0.250000 ( 0.258924)
# >> sort_by.reverse 0.250000 0.000000 0.250000 ( 0.245179)
# >> sort_by.reverse! 0.240000 0.000000 0.240000 ( 0.242340)
एक और हाल ही में मैकबुक प्रो पर रूबी 2.2.1 का उपयोग करके उपरोक्त कोड चलाने वाले नए परिणाम। फिर, सटीक संख्या महत्वपूर्ण नहीं हैं, यह उनके रिश्ते हैं:
Running Ruby 2.2.1
n=500
user system total real
sort 0.650000 0.000000 0.650000 ( 0.653191)
sort reverse 0.650000 0.000000 0.650000 ( 0.648761)
sort_by -a[:bar] 0.240000 0.010000 0.250000 ( 0.245193)
sort_by a[:bar]*-1 0.240000 0.000000 0.240000 ( 0.240541)
sort_by.reverse 0.230000 0.000000 0.230000 ( 0.228571)
sort_by.reverse! 0.230000 0.000000 0.230000 ( 0.230040)
रूबी 2.7.1 के लिए मध्य-2015 मैकबुक प्रो पर अपडेट किया गया:
Running Ruby 2.7.1
n=500
user system total real
sort 0.494707 0.003662 0.498369 ( 0.501064)
sort reverse 0.480181 0.005186 0.485367 ( 0.487972)
sort_by -a[:bar] 0.121521 0.003781 0.125302 ( 0.126557)
sort_by a[:bar]*-1 0.115097 0.003931 0.119028 ( 0.122991)
sort_by.reverse 0.110459 0.003414 0.113873 ( 0.114443)
sort_by.reverse! 0.108997 0.001631 0.110628 ( 0.111532)
... रिवर्स विधि वास्तव में एक उलट सरणी नहीं लौटाती है - यह एक एन्यूमरेटर देता है जो बस अंत में शुरू होता है और पीछे की ओर काम करता है।
के लिए स्रोत Array#reverse
है:
static VALUE
rb_ary_reverse_m(VALUE ary)
{
long len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);
if (len > 0) {
const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}
do *p2-- = *p1++; while (--len > 0);
अगर मैं अपने सी को सही ढंग से याद करता हूं तो पॉइंटर्स को तत्वों को उल्टे क्रम में कॉपी कर रहा है, इसलिए सरणी उलट है।