ASP에서 문자열을 연결할 때의 전형적인 방법은 다음과 같다:

strVariable = strVariable & "your new string"

이렇게 사용하는 것 자체에는 큰 문제가 없다. 하지만 상당히 많은 문자열을 연결시켜야 한다거나, 상당히 긴 문자열을 연결시킬 때에는 한 번쯤 문자열이 내부적으로 어떻게 연결되는지를 안 후 좀 더 좋은 방법을 찾아야 할 필요가 있다. ASP, VBScript는 문자열을 연결시킬 때 내부적으로 다음과 같은 작업을 한다:

  • 원래 문자열을 복사한다.
  • 연결시킬 새로운 문자열을 그 끝에 추가한다.
  • 원래 문자열을 새롭게 완성한 문자열로 대치시킨다.

간단한 문자열 연결 작업에는 전혀 문제가 없겠지만, 매우 사이즈가 큰 문자열이거나 연결시킬 문자열이 상당히 많을 때에는 이 내부 작업이 얼마나 비효율적일지는 짐작이 갈 것이다.

그래서 여기서는 상당히 긴 문자열이거나, 연결시킬 문자열이 많을 때의 문자열 연결 작업을 효율적으로 할 수 있는 클래스를 만들어 보도록 하겠다.

ASP에서 클래스를 만드는  방법에 대한 글은 다음을 참조하기 바란다.

여기서 만들 클래스의 이름은 StringBuilder이다. 이 클래스에 대한 코드는 다음과 같다:

' 문자열 연결 작업시 효율적으로 작업할 수 있는 StringBuilder 클래스
Class StringBuilder
        Dim arr         '연결시킬 문자열에 대한 배열
        Dim growthRate  '배열 크기 증가 비율
        Dim itemCount   '배열 요소 갯수
 
        Private Sub Class_Initialize()
                growthRate = 50
                itemCount = 0
                ReDim arr(growthRate)
        End Sub
 
        '새 문자열을 배열의 끝에 추가.
        '만일 배열 요소 수가 실제 배열 크기보다 크면
        'ReDim을 통하여 배열 사이즈 조정.
        Public Sub Append(ByVal strValue)
                If itemCount > UBound(arr) Then
                        ReDim Preserve arr(UBound(arr) + growthRate)
                End If
 
                arr(itemCount) = strValue
                itemCount = itemCount + 1
        End Sub
 
        '배열 요소 사이를 구분짓는 문자열이 없으므로
        '단순히 배열의 요소를 합치면 원하는 문자열이 된다.
        Public Function ToString()
                ToString = Join(arr, "")
        End Function
End Class

위 클래스를 사용하는 방법은 다음과 같다:

Dim objBuilder, i
Set objBuilder = new StringBuilder
 
For i = 0 To 500
        objBuilder.Append("my string " & i)
Next
 
Response.Write objBuilder.ToString()

이제 기존 문자열 연결 방식과 새로 배운 문자열 연결 방식의 스크립트 수행 시간을 비교해 보도록 하자.

이제 기존 문자열 연결 방식과 새로 배운 문자열 연결 방식의 스크립트 수행 시간을 비교해 보도록 하자. ASP 스크립트의 수행 시간을 재는 방법에 대해서는 다음 글을 참조하기 바란다:

단순한 테스트를 위해 for 문을 이용하여 문자열 연결을 2000회 반복하였을 경우 스크립트 수행 시간이 어떻게 차이가 나는지 살펴보도록 하자.

다음은 스크립트 수행 시간 비교를 위한 코드이다.

<%
' 문자열 연결 작업시 효율적으로 작업할 수 있는 StringBuilder 클래스
Class StringBuilder
        Dim arr         '연결시킬 문자열에 대한 배열
        Dim growthRate  '배열 크기 증가 비율
        Dim itemCount   '배열 요소 갯수
 
        Private Sub Class_Initialize()
                growthRate = 50
                itemCount = 0
                ReDim arr(growthRate)
        End Sub
 
        '새 문자열을 배열의 끝에 추가.
        '만일 배열 요소 수가 실제 배열 크기보다 크면
        'ReDim을 통하여 배열 사이즈 조정.
        Public Sub Append(ByVal strValue)
                If itemCount > UBound(arr) Then
                        ReDim Preserve arr(UBound(arr) + growthRate)
                End If
 
                arr(itemCount) = strValue
                itemCount = itemCount + 1
        End Sub
 
        '배열 요소 사이를 구분짓는 문자열이 없으므로
        '단순히 배열의 요소를 합치면 원하는 문자열이 된다.
        Public Function ToString()
                ToString = Join(arr, "")
        End Function
End Class
 
Dim StopWatch(2)
 
sub StartTimer(x)
'::::::::::::::::::::::::::::::::::::::::::::::::::::
':::     시간을 재기 시작할 때의 시간 저장        :::
'::::::::::::::::::::::::::::::::::::::::::::::::::::
   StopWatch(x) = timer
end sub
 
 
function StopTimer(x)
'::::::::::::::::::::::::::::::::::::::::::::::::::::
':::     여기서 시간을 멈추고 걸린 시간 계산.     :::
':::     하루 이상 걸릴 경우도 고려.              :::
':::     이 루틴은 가급적 1시간 이상 또는         :::
':::     100 밀리세컨즈 이하의 시간을 측정하는데는:::
':::     부적절하다.                              :::
'::::::::::::::::::::::::::::::::::::::::::::::::::::
   EndTime = Timer
 
   '자정을 넘겼을 경우의 처리...
   if EndTime < StopWatch(x) then
     EndTime = EndTime + (86400)
   end if
 
   StopTimer = EndTime - StopWatch(x)
end function

Response.Write "<b>기존 방식</b>" & "<br><br>"
 
StartTimer 1
 
For i = 0 To 2000
        strConcat = strConcat & "my string " & i
Next
 
Response.Write strConcat & "<br><br>"
 
Elapsed = StopTimer(1)
Response.Write "<b>수행시간: " & Elapsed  & "</b><br><br>"

Response.Write "<b>새로운 방식</b>" & "<br><br>"
 
StartTimer 2
 
Dim objBuilder, i
Set objBuilder = new StringBuilder
 
For i = 0 To 2000
        objBuilder.Append("my string " & i)
Next
 
Response.Write objBuilder.ToString() & "<br><br>"
 
Elapsed = StopTimer(2)
Response.Write "<b>수행시간: " & Elapsed & "</b>"
 
%>

네트웍 상황에 따라 결과가 서로 틀리게 나오긴 하겠지만 이 문서를 작성할 당시의 결과는 다음과 같다:

기존 방식

my string 0my string 1my string 2my string 3my string 4my string 5my string 6my string 7my string 8my string 9my string 10my string 11my string 12my string 13my string 14my string 15my string 16my string 17my string 18...
...
...

수행 시간 : 0.625

새로운 방식
 
my string 0my string 1my string 2my string 3my string 4my string 5my string 6my string 7my string 8my string 9my string 10my string 11my string 12my string 13my string 14my string 15my string 16my string 17my string 18...
...
...

수행 시간 : 0.15625

위 결과에 의하면 새로운 방식이 대략 4배 정도 빠른 것으로 나타난다. 하지만 반복 횟수가 더 많으면 많을 수록 그 차이는 더 발생할 것이다.

위 스크립트에 대한 실제 결과를 보고 싶은 사람은 아래 링크를 참조하기 바란다:

Posted by 엘로이티큐브IT개발팀 트랙백 0 : 댓글 1