[첫화면으로]Perl/StringConcatenationBenchmark

마지막으로 [b]

Perl의 String Concatenation 속도 측정

1. 개요
2. 실험 환경
3. 테스트 코드
4. 테스트 결과
4.1. straw
4.2. linux
4.3. 그래프
4.4. mul값을 10만~100만 사이에서 변경
4.5. active - Activestate perl의 경우
5. 그 외
6. (문서 업데이트)
7. 결론
8. 참고
9. Comments

1. 개요

2. 실험 환경

3. 테스트 코드

기본적으로 "1234567890" 스트링을 반복연결하여, 10글자, 100글자, ..., 천만 글자 길이의 스트링을 생성한다.

#!/usr/bin/perl
use strict;
use warnings;
use integer;
use Benchmark qw(:all);

my $str = "1234567890";     # 10글자 스트링

for (my $mul = 1; $mul <= 1_000_000; $mul *= 10) {
    print "==== mul = $mul ====\n";

    my $COUNT = 30_000_000 / $mul;

    my $results =
        timethese( $COUNT, {
            'x' =>
                sub {
                    my $long_str;
                    $long_str = $str x $mul;             # "x" 연산자를 사용하여 한 번에 원하는 길이의 스트링 생성
                },
            'dot' =>
                sub {
                    my $long_str;
                    for ( my $i = 1; $i <= $mul; $i++ ) {
                        $long_str .= $str;               # "." 연산자를 사용하여 10글자짜리 스트링을 계속 이어서 붙임
                    }
                },
        } );
    cmpthese($results);
}

4. 테스트 결과

4.1. straw

==== mul = 1 ====
Benchmark: timing 30000000 iterations of dot, x...
       dot: 17 wallclock secs (16.00 usr +  0.00 sys = 16.00 CPU) @ 1875117.19/s (n=30000000)
         x:  6 wallclock secs ( 6.02 usr +  0.00 sys =  6.02 CPU) @ 4986702.13/s (n=30000000)
         Rate  dot    x
dot 1875117/s   -- -62%
x   4986702/s 166%   --
==== mul = 10 ====
Benchmark: timing 3000000 iterations of dot, x...
       dot:  6 wallclock secs ( 6.72 usr +  0.00 sys =  6.72 CPU) @ 446495.01/s (n=3000000)
         x:  1 wallclock secs ( 1.20 usr +  0.00 sys =  1.20 CPU) @ 2493765.59/s (n=3000000)
         Rate  dot    x
dot  446495/s   -- -82%
x   2493766/s 459%   --
==== mul = 100 ====
Benchmark: timing 300000 iterations of dot, x...
       dot:  6 wallclock secs ( 5.86 usr +  0.00 sys =  5.86 CPU) @ 51194.54/s (n=300000)
         x:  1 wallclock secs ( 0.59 usr +  0.00 sys =  0.59 CPU) @ 505050.51/s (n=300000)
        Rate  dot    x
dot  51195/s   -- -90%
x   505051/s 887%   --
==== mul = 1000 ====
Benchmark: timing 30000 iterations of dot, x...
       dot:  6 wallclock secs ( 5.69 usr +  0.00 sys =  5.69 CPU) @ 5275.19/s (n=30000)
         x:  0 wallclock secs ( 0.53 usr +  0.00 sys =  0.53 CPU) @ 56497.18/s (n=30000)
       Rate  dot    x
dot  5275/s   -- -91%
x   56497/s 971%   --
==== mul = 10000 ====
Benchmark: timing 3000 iterations of dot, x...
       dot:  6 wallclock secs ( 5.72 usr +  0.00 sys =  5.72 CPU) @ 524.57/s (n=3000)
         x:  1 wallclock secs ( 0.58 usr +  0.00 sys =  0.58 CPU) @ 5190.31/s (n=3000)
      Rate  dot    x
dot  525/s   -- -90%
x   5190/s 889%   --
==== mul = 100000 ====
Benchmark: timing 300 iterations of dot, x...
       dot:  6 wallclock secs ( 5.89 usr +  0.02 sys =  5.91 CPU) @ 50.79/s (n=300)
         x:  0 wallclock secs ( 0.75 usr +  0.00 sys =  0.75 CPU) @ 400.00/s (n=300)
            (warning: too few iterations for a reliable count)
      Rate  dot    x
dot 50.8/s   -- -87%
x    400/s 688%   --
==== mul = 1000000 ====
Benchmark: timing 30 iterations of dot, x...
       dot: 21 wallclock secs (16.33 usr +  3.83 sys = 20.16 CPU) @ 1.49/s (n=30)
         x:  0 wallclock secs ( 0.73 usr +  0.00 sys =  0.73 CPU) @ 40.87/s (n=30)
            (warning: too few iterations for a reliable count)
      Rate   dot     x
dot 1.49/s    --  -96%
x   40.9/s 2646%    --

"@ 1.49/s" 형태로 적혀 있는 것은, 해당 서브루틴을 초당 1.49번 수행했다는 얘기다. mul값이 100에서 100,000 사이일 때 "dot"과 "x"의 초당 수행 횟수를 비교해보면 대략 9~10배 정도 차이가 난다. 그런데 mul값이 백만일 때를 보면 (제일 마지막 단락), 1.49/s와 40.87/s로 27배 차이가 나고 있다. "."연산을 백만 번 반복하는데 20초 정도나 걸린다.

4.2. linux

==== mul = 1 ====
Benchmark: timing 30000000 iterations of dot, x...
       dot: 16 wallclock secs (17.01 usr +  0.00 sys = 17.01 CPU) @ 1763668.43/s (n=30000000)
         x:  9 wallclock secs ( 8.16 usr +  0.00 sys =  8.16 CPU) @ 3676470.59/s (n=30000000)
         Rate  dot    x
dot 1763668/s   -- -52%
x   3676471/s 108%   --
==== mul = 10 ====
Benchmark: timing 3000000 iterations of dot, x...
       dot:  9 wallclock secs ( 7.26 usr +  0.00 sys =  7.26 CPU) @ 413223.14/s (n=3000000)
         x:  1 wallclock secs ( 1.54 usr +  0.00 sys =  1.54 CPU) @ 1948051.95/s (n=3000000)
         Rate  dot    x
dot  413223/s   -- -79%
x   1948052/s 371%   --
==== mul = 100 ====
Benchmark: timing 300000 iterations of dot, x...
       dot:  7 wallclock secs ( 6.30 usr +  0.00 sys =  6.30 CPU) @ 47619.05/s (n=300000)
         x:  1 wallclock secs ( 0.92 usr +  0.00 sys =  0.92 CPU) @ 326086.96/s (n=300000)
        Rate  dot    x
dot  47619/s   -- -85%
x   326087/s 585%   --
==== mul = 1000 ====
Benchmark: timing 30000 iterations of dot, x...
       dot:  6 wallclock secs ( 6.16 usr +  0.00 sys =  6.16 CPU) @ 4870.13/s (n=30000)
         x:  1 wallclock secs ( 0.85 usr +  0.00 sys =  0.85 CPU) @ 35294.12/s (n=30000)
       Rate  dot    x
dot  4870/s   -- -86%
x   35294/s 625%   --
==== mul = 10000 ====
Benchmark: timing 3000 iterations of dot, x...
       dot:  6 wallclock secs ( 6.13 usr +  0.00 sys =  6.13 CPU) @ 489.40/s (n=3000)
         x:  1 wallclock secs ( 1.00 usr +  0.00 sys =  1.00 CPU) @ 3000.00/s (n=3000)
      Rate  dot    x
dot  489/s   -- -84%
x   3000/s 513%   --
==== mul = 100000 ====
Benchmark: timing 300 iterations of dot, x...
       dot:  6 wallclock secs ( 6.12 usr +  0.00 sys =  6.12 CPU) @ 49.02/s (n=300)
         x:  1 wallclock secs ( 1.03 usr +  0.01 sys =  1.04 CPU) @ 288.46/s (n=300)
      Rate  dot    x
dot 49.0/s   -- -83%
x    288/s 488%   --
==== mul = 1000000 ====
Benchmark: timing 30 iterations of dot, x...
       dot:  7 wallclock secs ( 6.18 usr +  0.01 sys =  6.19 CPU) @  4.85/s (n=30)
         x:  1 wallclock secs ( 1.09 usr +  0.02 sys =  1.11 CPU) @ 27.03/s (n=30)
      Rate  dot    x
dot 4.85/s   -- -82%
x   27.0/s 458%   --

리눅스에서는 백만번 수행할 때도 다른 때와 같이 6배 정도밖에 차이가 나지 않는다.

4.3. 그래프

위 두 결과를 차트로 만들어 보았다.

Upload:bench_01.png

x(windows)와 dot(windows) 라인 사이의 간격이, mul값이 십만을 넘으면서 점점 벌어지는 것을 볼 수 있다. 그 두 값의 비율인 ratio 그래프를 보면, 결과적으로 ratio가 증가하고 있는데, 그래프의 y축이 로그 스케일인 걸 감안하면 상당히 급격히 늘어나는 것이다.

4.4. mul값을 10만~100만 사이에서 변경

mul값 10만과 100만 사이에서 급격히 차이가 벌어지는 곳을 발견할 수 있을까 해서, 값을 5만씩 증가시켜가면서 다시 측정해보았다. 표는 생략하고 그래프만 보이면

Upload:bench_02.png

딱히 눈에 띄는 포인트는 없고, 10만번일 때 이미 벌어지기 시작했던 것으로 보인다.

4.5. active - Activestate perl의 경우

"straw" 환경에서 백만번 반복할 때 속도가 현저하게 떨어진 것이, Strawberry Perl의 perl 인터프리터 구현의 문제일까 싶어서, Activestate사의 배포본을 다시 설치해서 테스트해보았는데, Strawberry Perl과 유사한 결과를 보였다 따라서 Perl 배포본의 문제는 아닌 것으로 보임.

결과 로그만 첨부함 - 클릭

5. 그 외

딱히 딸기 펄만의 문제가 아니라면 뭐가 문제일까?

그 외 생각할 수 있는 것은, 위 테스트에서 차이가 나는 부분을 생각하면

등등이 있을 법 한데, 이건 다른 상황에서 테스트한 결과를 얻을 때마다 소거해 나갈 수 있을 것이다.

6. (문서 업데이트)

aero님의 실험[3]에서 다음과 같이 확인됨

7. 결론

8. 참고

9. Comments

이름:  
Homepage:
내용:
 


컴퓨터분류

마지막 편집일: 2012-2-11 12:25 am (변경사항 [d])
1324 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기