2012-11-29 2 views
0

함수 f (1), f (2), ..., f (1e7)의 결과를 캐싱합니다. 캐시의 요소는 무작위로 읽혀집니다. C에서 액세스 복잡성은 O (1)이므로 벡터에 저장합니다. Perl에서는 캐시를 벡터 또는 해시에 저장해야합니까?배열 액세스 복잡성은 perl에서 O (1) 또는 O (n)입니까?

해시에 저장하는 것이 입력이 순차적 정수라는 사실을 이용하지 않을 것이라고 생각합니다. 그러나 다른 한편으로, 나는 아마 이것을 overthinking 해요.

+0

성능 차이는 측정 할 수 있습니까? 너 뭐 해봤 니? –

+0

@GregHewgill이 경우는 아니지만 배열 액세스가 O (n)이면 요소가 더 많을 것입니다. – Andreas

답변

2

프로파일 링 할 때까지 효율성에 대한 일반적인 면책 조항 이외에 어레이에 저장한다고 말하고 싶습니다. 해시는 해시 키 계산시 추가 오버 헤드를 부과합니다. 게다가, 배열은 가장 자연스러운 표현이며, 성능이 좋지 않다면 명확성을 위해 이동하십시오.

+3

해시와 배열 간의 속도 차이가 실제 코드에서는 무시할 수 있지만 성능은 속도와 관련이 없으며 메모리에 관한 것입니다. 해시의 장점 중 하나는 배열이 너무 희박하다는 것입니다. '$ cache [3] = $ value' 그리고 나서'$ cache [1_000_000] = $ value'을하면, 중간에있는 모든 빈 값에 대해 8 메가와 같은 것을 할당했습니다. 이것은 낭비가 아닌 영리한 공격자가이를 서비스 거부 공격으로 사용할 수 있습니다. – Schwern

+0

일반적으로 좋은 점을 명심해야하지만 OP는 입력이 순차적이라고 말했습니다. – RonaldBarzell

+2

오늘은 내일의 요구 사항을 알고있는 순차적입니다. 누가 그것을 유지할 것인지, 디자인의 한계를 깨닫게 될지 누가 알겠는가? 밀접하게 해시와 배열이 얼마나 잘 수행되는지 감안할 때, IMO는 위험할만한 가치가 없습니다. 순차적으로로드 되더라도 똑똑한 공격자 (또는 일반 사용자)가'cached_function (1_000_000_000) '을 요청하고 모든 메모리를 소비 할 수 있습니다. – Schwern

7

직접 함수 결과를 캐시하는 대신 Memoize core module을 사용하십시오.

use Memoize; 
memoize('slow_function'); 
slow_function(arguments); # Is faster than it was before 

그게 전부이며, 오랫동안 주변에 있었고 잘 테스트되었습니다.

+0

고마워, 난 항상 그런 것들을 수동으로 구현했습니다! – Andreas

+1

일반적으로 프로그래밍에 일반적인 펄을 쓰고 있는데, 매우 구체적인 요구에 맞는 것이 아니라면, 이미 그것을 할 수있는 모듈이 있습니다. ISBN을 확인 하시겠습니까? 비즈니스 :: ISBN. HTML 구문 분석? HTML :: 파서. 일치하는 정규식 (뭐든간에)? 정규식 :: 공통. 계속해서 코드를 작성해야한다면 CPAN에있을 것입니다. –

1

Perl에서 배열과 해시 모두 O (1)입니다. 하지만, 배열에 대한 O (1)은 절대 시계 시간이 더 빠르다고 생각합니다. 순차적 정수의 경우, 배열은 더 빠른 방법 일 수 있습니다. 그 간단한 지수는 수학적입니다.

0

존재하는 배열 요소에 액세스하는 것이 해시에 삽입하는 것보다 빠를 것입니다. 더하기 측면에서, 두 스케일의 성능은 유사합니다. (복잡성 분석 방법은 뭔가가 아니다 얼마나 빨리, 확장 얼마나 잘.)

배열 요소의

최악의 경우 액세스 : (한정된 길이 키) 해시 요소의

$x = $a[$i];   # O(1) 
$a[$i] = $x; $i<@a # O(1) 
$a[$i] = $x;   # O(1), amortized 

최악의 액세스 :

$x = $h{$k};   # O(1) 
$h{$k} = $x;   # O(1), amortized 

("상각 O (1)"의미는 이러한 작업의 N에 대한 (N) O입니다.)

당신의 키를 순차적 정수임을 감안할 때, 당신은 가장 확실히 배열을 사용해야합니다.

my @cache; 
sub func { 
    my ($n) = @_; 
    return $cache[$n] //= ...; 
} 

키가 희박한 경우 메모리를 절약하기 위해 해시를 사용하는 것이 좋습니다.

my %cache; 
sub func { 
    my ($n) = @_; 
    return $cache{$n} //= ...; 
} 
+0

나는 삽입에 관한 것이 아니라 접근에 대해 말하고 있었다. 필자의 경우 캐시를 만드는 것보다 캐시에 액세스하는 데 훨씬 많은 시간이 소비됩니다. – Andreas

+0

"상각"이란 무엇을 의미합니까? – Andreas

+0

액세스는 O (1)입니다. 조정 됨. 나는 할부 상환을 설명했다. – ikegami

관련 문제