2011-03-22 2 views
3

Perl에서 문자열 연결 속도는 얼마나 빠릅니까? 그것은 두 번째 피연산자의 길이에 선형입니까? 그렇다면이 작업이 선형이어야하는 조건은 무엇입니까? 비선형 연결 시간의 예는 무엇입니까?Perl에서 문자열 연산은 얼마나 빠릅니까? 특히 연결과 할당

문자열 할당은 어떻게됩니까? 버퍼의 실제 복사본은 언제 어디서 발생합니까?

부분 문자열 또는 간단한 정규식과 같은 다른 연산은 어떻게됩니까?

+4

쓰기를 시도 할 수있는 재미있는 기회 것 같은데 일부 벤치마킹 도구. 지난 번 내가했던 것처럼 Perl이 "단순한"손으로 쓴 C를 포함한 다른 많은 도구보다 훨씬 더 빠르다는 것에 놀랐다. – sarnold

+0

연결은 전체 길이에 대해 선형 일 가능성이 큽니다. 적어도 줄 단위로 읽는 동안 1 + MB 파일을 연결하려고하면 엉망 이었지만 join ("", @input)은 비교적 빠르게 실행되었습니다. (나는 그때에 도둑질을했다는 것을 몰랐다.) – Dallaylaen

답변

2

나는 이것을 직접 테스트했다. 연결은 두 번째 인수의 길이에 선형이지만 할당은 항상 문자열의 길이에 선형입니다.

Perl은 문자열에 대한 참조를 계산하지 않지만 버퍼를 모든 변수 (참조)와 연결하는 것처럼 보입니다.

병합이 일정한 것으로 보인다 전체 테스트 선형 :

248ms my $x; $x .= "a" for 1..2_000_000 
501ms my $x; $x .= "a" for 1..4_000_000 
967ms my $x; $x .= "a" for 1..8_000_000 

$x = $x . $y 최적화 할 것이 경우 $x 버퍼 사용

295ms my $x; $x = $x . "a" for 1..2_000_000 
592ms my $x; $x = $x . "a" for 1..4_000_000 
1170ms my $x; $x = $x . "a" for 1..8_000_000 
여기

일부 테스트 결과이다

이전 최적화가 정적으로 수행 된 것처럼 보이므로 다음 테스트의 연결이 결과 문자열 길이에 선형입니다. 분노 시험은 차입니다 :

233ms my $x; ${\$x} = ${\$x} . "a" for 1..40_000 
951ms my $x; ${\$x} = ${\$x} . "a" for 1..80_000 
3811ms my $x; ${\$x} = ${\$x} . "a" for 1..160_000 

복사는 선형 :

모든 사본은 선형, 참조 횟수는 문자열을 사용하지 않는됩니다
186ms my $x; for (1..50_000) { $x .= "a"; my $y = $x } 
764ms my $x; for (1..100_000) { $x .= "a"; my $y = $x } 
3029ms my $x; for (1..200_000) { $x .= "a"; my $y = $x } 

:

545ms my $x; for (1..50_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x } 
2264ms my $x; for (1..100_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x } 
8951ms my $x; for (1..200_000) { $x .= "a"; my $y = $x; my $y2 = $x; my $y3 = $x } 
5

이 정말 복잡한 질문과 대답은 지금까지 여러 가지 요인 (아키텍처, OS를 기본, HW, 펄 컴파일 플래그 등)

아이디어를 얻으려면, 당신은 펄 구조의 내부를 살펴 수에 따라 다릅니다 변수를 나타내는 데 사용됩니다. 좋은 출처는 perlguts illustrated입니다.

당신이 마음에 고유의 구현이있는 경우

은, 코드를 벤치마킹하려고 :

use Benchmark qw(:all); 

my $a = "Some string"; 
my @b = map { "Some string to append " x $_ } (1..10); 

cmpthese(-1, { 
    (map {+ "concat_$_" => sub { my $c = $a . $b[$_] } } (1..10)) 
}); 

것은 위의 두 번째 인수의 다양한 길이 동작 my $c = $a . $b를 비교합니다. 결과에서이 길이 범위에 대해 작업은 대략 선형 시간으로 실행됨을 알 수 있습니다.

+0

@cjm - 고마워요. 나는 그것이 버전이 아닌 버전을 가지고 있다는 것을 몰랐다. – bvr

+0

+1 perlguts 링크 - 감사합니다. 질문에 대답하지 않고 일반적으로 너무 모호하기 때문에 나는이 형태로이 대답을 받아 들일 수 없다.기본 OS가 문자열 연결의 복잡성과 아무 관련이 없을 것이라고 생각하지 않습니다. (여기에서 기대하지 않았던 malloc 복잡성을 분석하는 것만 큼 깊지는 않을 것입니다. – agsamek

관련 문제