2012-08-16 2 views
2

루비에서는 중복 요소가 없어야하는 (아마도 커다란) 배열을 생성하고 리턴하는 메소드를 빌드하고 있습니다. 집합을 사용하고 배열로 변환하여 성능을 향상시킬 수 있습니까? 아니면 내가 그것을 반환하기 전에 사용하고 배열에 .uniq를 호출하는 것이 더 낫겠습니까? 또는 배열 += 대신에 &을 사용하여 항목을 추가하는 것은 어떻습니까? 그리고 내가 세트를 사용한다면, 세트에 넣고있는 객체에 <=> 메소드를 가지지 않을 경우 성능에 영향을 미칩니 까? (확실하지 않은 경우이를 테스트하는 방법을 알고 있습니까?)세트 성능 루비의 배열

답변

5

진짜 대답은 가장 읽기 쉽고 유지 보수가 가능한 코드를 작성하고 그것이 병목 현상이라고 표시 한 후에 만 ​​최적화하는 것입니다. 알고리즘이 is in linear time 인 경우 알고리즘을 최적화 할 필요가 없습니다. 여기가 ... 당신이 제안하는 방법을 아주 확실하지

을 쉽게 찾을 수 있지만, 내 fruity 보석을 사용하여 :

require 'fruity' 
require 'set' 

enum = 1000.times 

compare do 
    uniq { enum.each_with_object([]){|x, array| array << x}.uniq } 
    set { enum.each_with_object(Set[]){|x, set| set << x}.to_a } 
    join { enum.inject([]){|array, x| array | [x]} } 
end 

# set is faster than uniq by 10.0% ± 1.0% 
# uniq is faster than join by 394x ± 10.0 

을 분명히, 그것은 세 번째 방법처럼 중간 배열을 구축 이해되지 않는다. 그렇지 않으면, 당신이 O(n)에있을 것이기 때문에 큰 차이를 만들지 않을 것입니다; 그게 중요한거야. BTW

, 모두 sets, uniqArray#| 사용하여 객체에 eql?hash하지 <=>. 기본값은 객체가 ( this question 참조) 인 경우가 아니면 eql?이 아닙니다.

을 기본값으로 사용하므로 절대로 정의 할 필요가 없습니다.
3

Benchmark 라이브러리를 사용해 보셨습니까? 테스트는 일반적으로 매우 쉽게 구성 할 수 있으며 특정 버전의 Ruby에서 작동하는 방식을 올바르게 반영합니다.