다양한 제안 된 답변에 대한 벤치 마크를 수행하는 것이 항상 깨달았습니다. 내가 찾은 것은 다음과 같습니다.
#! / usr / bin / ruby
'벤치 마크'가 필요합니다
ary = []
1000. 회 {
ary << {: bar => rand (1000)}
}
n = 500
Benchmark.bm (20) do | x |
x.report ( "sort") {n.times {ary.sort {| a, b | b [: bar] <=> a [: bar]}}}
x.report ( "sort reverse") {n.times {ary.sort {| a, b | a [: bar] <=> 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.sort_by {| a | a [: bar] *-1}}}
x.report ( "sort_by.reverse!") {n.times {ary.sort_by {| a | a [: bar]} .reverse}}
종료
사용자 시스템 총 실제
정렬 3.960000 0.010000 3.970000 (3.990886)
역순 정렬 4.040000 0.000000 4.040000 (4.038849)
sort_by -a [: bar] 0.690000 0.000000 0.690000 (0.692080)
sort_by a [: bar] *-1 0.700000 0.000000 0.700000 (0.699735)
sort_by.reverse! 0.650000 0.000000 0.650000 (0.654447)
@ Pablo 's sort_by{...}.reverse!
가 가장 빠르다는 것이 흥미 롭습니다 . 테스트를 실행하기 전에 " -a[:bar]
" 보다 느릴 것이라고 생각 했지만 값을 부정하면 전체 배열을 한 번에 뒤집는 것보다 시간이 오래 걸립니다. 별 차이는 없지만 모든 작은 속도 향상이 도움이됩니다.
Ruby 1.9에서는 이러한 결과가 다릅니다.
다음은 Ruby 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)
오래된 MacBook Pro에 있습니다. 새롭거나 더 빠른 컴퓨터는 더 낮은 값을 갖지만 상대적인 차이는 유지됩니다.
다음은 최신 하드웨어에서 약간 업데이트 된 버전과 2.1.1 버전의 Ruby입니다.
#!/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)
최신 Macbook Pro에서 Ruby 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)
2015 년 중순 MacBook Pro에서 Ruby 2.7.1 용으로 업데이트 :
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);
C를 올바르게 기억하면 배열이 역순으로 요소에 대한 포인터를 역순으로 복사합니다.