codememo

범위() VS 셀() - 실행 시간

tipmemo 2023. 8. 26. 11:55
반응형

범위() VS 셀() - 실행 시간

나는 이 사이트에서 많은 VBA 코드를 봅니다.Range와의 방법.For루프:

Range("A" & i)

적절한 것과는 대조적으로.Cells명령:

Cells(i,1)

나는 항상 알고 있었습니다.Cells방법이 더 빠릅니다, 부분적으로 이유는.Range해결하는 데 시간이 더 오래 걸리고, 부분적으로는 연결(&)는 상대적으로 느린 프로세스입니다(다른 간단한 산술 연산(AFAIK)과는 대조적입니다).

문제는 이게 정말 더 빠르냐는 것입니다.얼마나?가끔은.Range포맷은 특히 초보자들에게 더 읽기 쉽습니다.속도 향상이 약간의 불편함과 답변에 필요한 추가 설명을 정당화합니까?

저는 무엇이 무엇인지 알아보기 위해 몇 가지 테스트를 해봤습니다.

방법

저는 네 가지 시나리오의 속도를 테스트했습니다.각 테스트는 100,000 사이클을 수행하는 For 루프로 구성되었습니다.이 테스트의 핵심은 명령문을 사용하여 세포를 "잡는" 것입니다.

For i = 1 To 100000
  With Cells(i, 1)
  End With
Next i

네 가지 테스트는 다음과 같습니다.

  • 세포, 가변 세포 -With Cells(i, 1)

  • 셀, 단일 셀 -With Cells(1, 1)

  • 범위, 가변 셀 -With Range("A" & i)

  • 범위, 단일 셀 -Range("A1")

저는 4개의 테스트 케이스에 별도의 서브를 사용했고, 5번째 서브를 사용하여 각각 500번씩 실행했습니다.아래 코드를 참조하십시오.

시간 측정을 위해 GetTickCount를 사용하여 밀리초의 정확도를 얻었습니다.

결과.

500회 측정한 결과, 결과는 매우 일관적이었습니다. (100회 반복하여 여러 번 실행했지만 거의 동일한 결과를 얻었습니다.)

          Cells     Cells     Range     Range
        (variable) (single) (variable) (single)
avg       124,3     126,4     372,0     329,8
median     125       125       374       328
mode       125       125       374       328
stdev      4,1       4,7       5,7       5,4
min        109       124       358       327
max        156       141       390       344

Measurement results

해석

Cells방법이 동급 제품보다 2.6배 빠름Range방법.연결을 사용하는 경우 실행 시간이 10% 더 추가되므로 거의 3배 차이가 납니다.이것은 큰 차이입니다.

그러나 다른 한편으로는 셀당 평균 0.001ms 대 0.004ms에 대해 이야기하고 있습니다.우리가 2-30만 개 이상의 셀에서 스크립트를 실행하지 않는 한, 이것은 눈에 띄는 속도 차이를 만들지 못할 것입니다.

결론

네, 속도 차이가 많이 납니다.

아니요, 저는 사람들에게 엄청난 양의 세포를 처리하지 않는 한 Cells 방법을 사용하라고 말하지 않을 것입니다.

테스트 설정

  • Win7 64비트
  • 8GB RAM
  • Intel Core i7-3770 @ 3.40GHz
  • 엑셀 2013 32비트

제가 놓친 게 있나요?내가 뭘 잘못했나요?주저하지 말고 지적해 주세요!건배! :)

코드

Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub testCells(j As Long)
  Dim i As Long
  Dim t1 As Long
  Dim t2 As Long
  t1 = GetTickCount
    For i = 1 To 100000
      With Cells(i, 1)
      End With
    Next i
  t2 = GetTickCount
  Sheet4.Cells(j, 1) = t2 - t1
End Sub
Sub testRange(j As Long)
  Dim i As Long
  Dim t1 As Long
  Dim t2 As Long
  t1 = GetTickCount
    For i = 1 To 100000
      With Range("A" & i)
      End With
    Next i
  t2 = GetTickCount
  Sheet4.Cells(j, 2) = t2 - t1
End Sub
Sub testRangeSimple(j As Long)
  Dim i As Long
  Dim t1 As Long
  Dim t2 As Long
  t1 = GetTickCount
    For i = 1 To 100000
      With Range("A1")
      End With
    Next i
  t2 = GetTickCount
  Sheet4.Cells(j, 3) = t2 - t1
End Sub
Sub testCellsSimple(j As Long)
  Dim i As Long
  Dim t1 As Long
  Dim t2 As Long
  t1 = GetTickCount
    For i = 1 To 100000
      With Cells(1, 1)
      End With
    Next i
  t2 = GetTickCount
  Sheet4.Cells(j, 4) = t2 - t1
End Sub

Sub runtests()
  Application.ScreenUpdating = False
  Application.Calculation = xlCalculationManual
  Dim j As Long

  DoEvents
  For j = 1 To 500
    testCells j
  Next j

  DoEvents
  For j = 1 To 500
    testRange j
  Next j

  DoEvents
  For j = 1 To 500
    testRangeSimple j
  Next j

  DoEvents
  For j = 1 To 500
    testCellsSimple j
  Next j

  Application.Calculation = xlCalculationAutomatic
  Application.ScreenUpdating = True

  For j = 1 To 5
    Beep
    DoEvents
  Next j

End Sub

저는 다음의 예를 본 후 테스트를 확장했습니다..Cells(1, "A")가독성 사이의 좋은 균형이 될 것이라고 생각했던 표기법.Range("A1").Cells(1, 1)

되었습니다..Cells(1, "A") 69의 시간으로 실행됩니다..Range("A1")그리고..Cells(1, 1)의 절반의 시간으로 실행되는.Range("A1")쓰기의 경우 차이가 더 작았습니다(각각 ~88% 및 82%).

코드:

Option Explicit
Sub test()
Dim i, x, y, a, t1, t2, t3, t4
x=1000000
y=x/100
Debug.Print "---Read---" 'Cell A1 contains the number 55
t1=Timer*1000
For i = 1 to x
    a = Sheet1.Range("A1")
Next
t2=Timer*1000
Debug.Print t2 - t1 & "ms"
For i = 1 to x
    a = Sheet1.Cells(1, "A")
Next
t3=Timer*1000
Debug.Print t3 - t2 & "ms (" & Round(100*(t3-t2)/(t2-t1),1)&"%)"
For i = 1 to x
    a = Sheet1.Cells(1, "A")
Next
t4=Timer*1000
Debug.Print t4 - t3 & "ms (" & Round(100*(t4-t3)/(t2-t1),1)&"%)"
Debug.Print "---Write---"    
a=55
t1=Timer*1000
For i = 1 to y
    Sheet1.Range("A1") = a
Next
t2=Timer*1000
Debug.Print t2 - t1 & "ms"
For i = 1 to y
    Sheet1.Cells(1, "A") = a
Next
t3=Timer*1000
Debug.Print t3 - t2 & "ms (" & Round(100*(t3-t2)/(t2-t1),1)&"%)"
For i = 1 to y
    Sheet1.Cells(1, "A") = a
Next
t4=Timer*1000
Debug.Print t4 - t3 & "ms (" & Round(100*(t4-t3)/(t2-t1),1)&"%)"
Debug.Print "----"
End Sub

^수기로 기록, 오타가 포함될 수 있음...

플랫폼:
32비트【 32】
7 7 64비트
RAM 16GB RAM
표준 E5-1650 v2 @3.5GHz

(편집: 코드의 쓰기 섹션에서 "x"를 "y"로 변경했습니다. 핸드헬드 코드에 대한 고지 사항 참조!)

성능을 향상시키는 방법을 추가로 설명하는 이 스택 오버플로 질문을 연결할 가치가 있습니다.

셀에서 느린 VBA 매크로 쓰기

언급URL : https://stackoverflow.com/questions/36073943/range-vs-cells-run-times

반응형