범위() 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
해석
그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"로 변경했습니다. 핸드헬드 코드에 대한 고지 사항 참조!)
성능을 향상시키는 방법을 추가로 설명하는 이 스택 오버플로 질문을 연결할 가치가 있습니다.
언급URL : https://stackoverflow.com/questions/36073943/range-vs-cells-run-times
'codememo' 카테고리의 다른 글
| 왜 스위프트에서 레트인 프로토콜을 사용할 수 없습니까? (0) | 2023.08.26 |
|---|---|
| 'rxjs-compat/Observable' 모듈을 찾을 수 없습니다. (0) | 2023.08.26 |
| iOS 4.0 iTunes Backup에서 Manifest.mbdb 파일을 구문 분석하는 방법 (0) | 2023.08.26 |
| Spring Data에서 날짜별로 마지막으로 주문한 레코드 가져오기 (0) | 2023.08.26 |
| Swift UIV뷰 배경색 불투명도 (0) | 2023.08.26 |
