[첫화면으로]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])
1502 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기