효율적인 소프트웨어란 무엇인가? 효율적인 소프트웨어는 동일한 기능을 수행하는 소프트웨어보다 빠르게 실행되어야 할 뿐만 아니라 시스템 리소스를 더 적게 소비해야 합니다. 이 기사에서는 저자가 소프트웨어 개발을 위해 VB를 사용하면서 축적한 경험을 종합하고 몇 가지 간단한 예제를 사용하여 효율적인 VB 코드를 작성하는 방법을 보여줍니다. 여기에는 VB 프로그래머에게 매우 도움이 될 수 있는 몇 가지 기술이 포함되어 있습니다. 시작하기 전에 몇 가지 개념을 명확히 하겠습니다.
코드를 한 번에 구체화시키십시오. 제가 접촉한 프로그래머들 중 많은 사람들은 기능 요구 사항에 따라 먼저 코드를 작성한 다음 이를 기반으로 코드를 최적화하는 것을 좋아합니다. 결국 그들은 최적화를 달성하려면 코드를 다시 작성해야 한다는 사실을 발견했습니다. 따라서 코드를 작성하기 전에 최적화 문제를 고려하는 것이 좋습니다.
최적화 결과와 필요한 작업 사이의 관계를 이해합니다. 일반적으로 코드 조각이 완료되면 코드를 검사하고 수정해야 합니다. 코드를 검사하는 과정에서 일부 루프의 코드 효율성이 더욱 향상될 수 있다는 것을 알 수 있습니다. 이 경우 완벽함을 추구하는 많은 프로그래머들은 즉시 코드를 수정하기도 합니다. 내 제안은 이 코드를 변경하면 프로그램 실행 시간이 1초 단축된다면 코드를 변경할 수 있다는 것입니다. 10밀리초 정도의 성능 향상만 가져올 수 있는 경우에는 변경 사항이 적용되지 않습니다. 코드 조각을 다시 작성하면 필연적으로 새로운 오류가 발생하고, 새 코드를 디버깅하려면 일정 시간이 걸리기 때문입니다. 프로그래머는 소프트웨어 성능과 소프트웨어 개발에 필요한 작업량 사이의 균형을 찾아야 하며, 10밀리초는 사용자가 인식할 수 없는 차이입니다.
필요한 경우 객체 지향 방법을 사용해 보십시오. VB에서 제공하는 메커니즘은 객체 지향 설계 및 코딩을 완벽하게 지원하지 않지만 VB는 간단한 클래스를 제공합니다. 대부분의 사람들은 객체를 사용하면 코드 효율성이 떨어진다고 믿습니다. 이 점에 대해서는 개인적으로 의견이 다릅니다. 코드의 효율성은 실행 속도의 관점에서만 평가할 수 없습니다. 소프트웨어가 차지하는 리소스도 고려해야 할 요소 중 하나입니다. 클래스를 사용하면 소프트웨어의 전반적인 성능을 향상시키는 데 도움이 될 수 있습니다. 이에 대해서는 나중에 예제에서 자세히 설명하겠습니다.
VB 코드를 작성할 때 위의 사항을 코딩의 원칙으로 활용하시기 바랍니다. 나는 기사를 코드의 실행 속도를 향상시키는 방법과 컴파일 최적화의 두 부분으로 나누었습니다.
코드를 더 빠르게 실행하는 방법
다음 방법은 코드 속도를 향상시키는 데 도움이 될 수 있습니다.
1. 정수(Integer)와 긴 정수(Long)를 사용하세요
코드를 더 빠르게 실행하는 가장 쉬운 방법은 올바른 데이터 유형을 사용하는 것입니다. 믿기지 않으실 수도 있지만 올바른 데이터 유형을 선택하면 코드 성능이 크게 향상될 수 있습니다. 대부분의 경우 프로그래머는 Single, Double 및 통화 유형 변수를 Integer 또는 Long 유형 변수로 바꿀 수 있습니다. VB의 Integer 및 Long 처리 능력이 다른 데이터 유형보다 훨씬 높기 때문입니다.
대부분의 경우 프로그래머가 Single 또는 Double을 사용하는 이유는 소수점 이하 자릿수를 저장할 수 있기 때문입니다. 그러나 소수는 정수 유형의 변수에 저장될 수도 있습니다. 예를 들어, 프로그램에서 소수점 세 자리가 합의된 경우 Integer 변수에 저장된 값을 1000으로 나누기만 하면 결과를 얻을 수 있습니다. 내 경험에 따르면 Single, Double 및 통화 대신 Integer 및 Long을 사용하면 코드가 거의 10배 더 빠르게 실행될 수 있습니다.
2. 변형 사용을 피하세요
VB 프로그래머에게는 이것이 분명합니다. Variant 유형의 변수에는 데이터를 저장하는 데 16바이트의 공간이 필요한 반면, 정수(Integer)에는 2바이트만 필요합니다. 일반적으로 변형 유형을 사용하는 목적은 설계 작업량과 코드 양을 줄이는 것입니다. 일부 프로그래머는 문제를 줄이기 위해 이를 사용하기도 합니다. 그러나 소프트웨어가 사양에 따라 엄격하게 설계되고 코딩된 경우 변형 유형의 사용을 완전히 피할 수 있습니다.
그런데 Object 개체에도 동일한 문제가 존재합니다. 아래 코드를 살펴보십시오.
mFSO
SetFSO=NewScripting.FileSystemObject
또는
DimFSO객체
SetFSO=NewScripting.FileSystemObject
위 코드는 선언 시 데이터 타입을 지정하지 않기 때문에 할당 시 메모리와 CPU 시간이 낭비됩니다. 올바른 코드는 다음과 같습니다.
DimFSOasNewFileSystemObject
3. 속성 사용을 피하십시오
일상적인 코드에서 가장 흔히 발생하는 비효율적인 코드는 변수를 사용할 수 있는 상황에서 속성(Property)을 반복적으로 사용하는 것, 특히 루프에서 그렇습니다. 변수에 접근하는 속도는 속성에 접근하는 속도의 약 20배라는 것을 알아야 합니다. 다음 코드는 많은 프로그래머가 프로그램에서 사용합니다.
DimintConas정수
ForintCon=0toUbound(SomVar())
Text1.Text=Text1.Text&vbcrlf&SomeVar(intCon)
NextintCon
아래 코드는 위 코드보다 20배 빠르게 실행됩니다.
DimintConas정수
DimsOutputasString
ForintCon=0toUbound(SomeVar())
sOutput=s출력&vbCrlf&
SomeVar(intCon)
다음
Text1.Text=sOutput
4. 배열을 사용하고 집합 사용을 피하세요
컬렉션을 사용해야 하는 경우가 아니면 항상 배열을 사용해야 합니다. 테스트에 따르면 배열의 액세스 속도는 컬렉션의 액세스 속도의 100배에 달할 수 있습니다. 이 숫자는 다소 충격적으로 들리지만 컬렉션이 객체라는 점을 고려하면 그 차이가 왜 그렇게 큰지 이해할 수 있습니다.
5. 작은 루프 본체를 확장합니다.
코딩할 때 다음과 같은 상황이 발생할 수 있습니다. 루프 본문은 2~3회만 반복되며 루프 본문은 여러 줄의 코드로 구성됩니다. 이 경우 루프를 풀 수 있습니다. 그 이유는 루프가 추가 CPU 시간을 차지하기 때문입니다. 그러나 루프가 더 복잡하다면 이 작업을 수행할 필요가 없습니다.
6. 너무 짧은 함수는 사용하지 마세요.
작은 루프를 사용할 때와 마찬가지로 몇 줄의 코드만으로 함수를 호출하는 것은 비경제적입니다. 함수 호출은 함수에서 코드를 실행하는 것보다 시간이 더 오래 걸릴 수 있습니다. 이 경우 함수가 원래 호출되었던 위치에 함수의 코드를 복사할 수 있습니다.
7. 하위 개체에 대한 참조를 줄입니다.
VB에서는 객체 참조가 . 예를 들어:
양식1.텍스트1.텍스트
위의 예에서 프로그램은 Form1과 Text1이라는 두 개체를 참조합니다. 이 방법으로 인용하는 것은 비효율적입니다. 그러나 불행하게도 이를 피할 수 있는 방법은 없습니다. 프로그래머가 할 수 있는 유일한 일은 With를 사용하거나 하위 개체(Text1)를 다른 개체와 함께 저장하는 것입니다.
참고: 함께 사용
WithfrmMain.Text1
.Text="LearnVB"
.정렬=0
.Tag="이츠마이라이프"
.BackColor=vbBlack
.ForeColor=vbWhite
끝
또는
참고: 하위 개체를 저장하려면 다른 개체를 사용하세요.
DimtxtTextBoxasTextBox
SettxtTextBox=frmMain.Text1
TxtTextBox.Text="LearnVB"
TxtTextBox.Alignment=0
TxtTextBox.Tag="Itsmylife"
TxtTextBox.BackColor=vbBlack
TxtTextBox.ForeColor=vbWhite
위에서 언급한 방법은 개체의 하위 개체에 대해 작업해야 하는 경우에만 적용 가능합니다. 다음 코드는 올바르지 않습니다.
텍스트 포함1
.Text="LearnVB"
.정렬=0
.Tag="이츠마이라이프"
.BackColor=vbBlack
.ForeColor=vbWhite
끝
불행하게도 실제 코드에서는 위와 유사한 코드를 종종 발견할 수 있습니다. 그렇게 하면 코드 실행 속도가 느려질 뿐입니다. 그 이유는 With 블록이 컴파일 후에 분기를 형성하여 추가 처리 작업이 추가되기 때문입니다.
8. 문자열이 비어 있는지 확인
대부분의 프로그래머는 문자열이 비어 있는지 확인할 때 다음 방법을 사용합니다.
IfText1.Text=""그러면
참고: 작업 수행
엔디프
불행하게도 문자열 비교를 수행하려면 속성을 읽는 것보다 더 많은 처리가 필요합니다. 따라서 다음 방법을 사용하는 것이 좋습니다.
IfLen(Text1.Text)=0then
참고: 작업 수행
엔디프
9. Next 키워드 삭제 후 변수명
Next 키워드 뒤에 변수 이름을 추가하면 코드 효율성이 떨어집니다. 왜 이런 일이 발생하는지 모르겠습니다. 단지 경험 일뿐입니다. 그러나 불필요한 정보를 추가하는 프로그래머는 거의 없다고 생각합니다. 결국 대부분의 프로그래머는 금과 같은 단어를 소중히 여기는 사람들입니다.
댓글: 잘못된 코드
ForiCount=1to10
참고: 작업 수행
NextiCount
참고: 올바른 코드
ForiCount=1to10
참고: 작업 수행
다음
10. 여러 변수 대신 배열을 사용하세요
유사한 데이터를 포함하는 변수가 여러 개 있는 경우 해당 변수를 배열로 바꾸는 것이 좋습니다. VB에서 배열은 가장 효율적인 데이터 구조 중 하나입니다.
11. 정적 배열 대신 동적 배열을 사용하세요
동적 배열을 사용하면 코드 실행 속도에 큰 영향을 미치지 않지만 경우에 따라 많은 리소스를 절약할 수 있습니다.
12. 객체 파괴
어떤 종류의 소프트웨어를 작성하든 프로그래머는 사용자가 소프트웨어를 종료하기로 결정한 후 소프트웨어가 차지하는 메모리 공간을 해제하는 것을 고려해야 합니다. 그러나 불행하게도 많은 프로그래머들은 이에 대해 그다지 관심을 두지 않는 것 같습니다. 올바른 접근 방식은 프로그램을 종료하기 전에 프로그램에 사용된 개체를 삭제하는 것입니다. 예를 들어:
DimFSOasNewFileSystemObject
참고: 작업 수행
참고: 개체를 파괴하세요.
SetFSO=아무것도 없음
양식의 경우 다음을 제거할 수 있습니다.
메인 언로드
또는
SetfrmMain=아무것도 없음
13. 가변 길이 및 고정 길이 문자열
기술적으로 말하면 고정 길이 문자열은 가변 길이 문자열보다 처리 시간과 공간이 덜 필요합니다. 그러나 고정 길이 문자열의 단점은 많은 경우 Trim 함수를 호출하여 문자열 끝의 null 문자를 제거해야 하므로 코드 효율성이 떨어진다는 것입니다. 따라서 문자열 길이가 변경되지 않는 한 가변 길이 문자열을 사용하십시오.
14. ActiveX 컨트롤 대신 클래스 모듈을 사용하세요.
ActiveX 컨트롤에 사용자 인터페이스가 포함되지 않는 한 클래스와 같은 경량 개체를 사용해 보십시오. 둘 사이에는 효율성의 큰 차이가 있습니다.
15. 내부 개체 사용
ActiveX 컨트롤과 DLL을 사용할 때 많은 프로그래머는 이를 컴파일한 다음 프로젝트에 추가하는 것을 좋아합니다. VB에서 외부 개체에 연결하려면 많은 CPU 처리 능력이 필요하기 때문에 이렇게 하지 않는 것이 좋습니다. 메서드를 호출하거나 속성에 액세스할 때마다 시스템 리소스가 많이 낭비됩니다. ActiveX 컨트롤이나 DLL에 대한 소스 코드가 있는 경우 프로젝트에서 이를 개인 개체로 만듭니다.
16. 모듈 수 줄이기
어떤 사람들은 공통 기능을 모듈에 유지하는 것을 좋아하는데 나도 이에 동의합니다. 하지만 하나의 모듈에 20~30줄의 코드만 작성하는 것은 좀 우스꽝스럽습니다. 모듈이 꼭 필요하지 않다면 사용하지 마세요. 그 이유는 VB가 모듈의 함수나 변수가 호출될 때만 모듈을 메모리에 로드하기 때문입니다. 이러한 모듈은 VB 응용 프로그램이 종료될 때 메모리에서 언로드됩니다. 코드에 모듈이 하나만 있으면 VB는 로드 작업을 하나만 수행하므로 코드 효율성이 향상됩니다. 반대로 코드에 모듈이 여러 개 있으면 VB는 여러 로드 작업을 수행하므로 효율성이 향상됩니다. 코드가 줄어들 것입니다.
17. 객체 배열을 사용하세요
사용자 인터페이스를 디자인할 때 프로그래머는 동일한 유형의 컨트롤에 대해 개체 배열을 사용하도록 노력해야 합니다. 실험을 할 수 있습니다. 각각 다른 이름을 가진 100개의 PictureBox를 창에 추가하고 프로그램을 실행하십시오. 그런 다음 새 프로젝트를 만들고 창에 100개의 PictureBox를 추가합니다. 하지만 이번에는 개체 배열을 사용하여 프로그램을 실행하면 두 프로그램의 로딩 시간 차이를 확인할 수 있습니다.
18. Move 메서드를 사용하세요
객체의 위치를 변경할 때 일부 프로그래머는 Width, Height, Top 및 Left 속성을 사용하기를 좋아합니다. 예를 들어:
이미지1.너비=100
이미지1.높이=100
이미지1.Top=0
이미지1.왼쪽=0
실제로 프로그램이 네 가지 속성을 수정하고 각 수정 후에 창이 다시 그려지기 때문에 이는 매우 비효율적입니다. 올바른 접근 방식은 Move 메서드를 사용하는 것입니다.
이미지1.이동0,0,100,100
19. 이미지 사용을 줄인다
사진은 많은 메모리를 차지하며, 사진을 처리하는 데에도 많은 CPU 리소스가 사용됩니다. 소프트웨어에서는 가능하다면 그림 대신 배경색을 사용하는 것을 고려하십시오. 물론 이는 이 문제에 대한 기술 담당자의 관점일 뿐입니다.
20. ActiveX 컨트롤 대신 ActiveXDLL을 사용하세요
디자인 중인 ActiveX 개체에 사용자 인터페이스가 포함되어 있지 않으면 ActiveXDLL을 사용하십시오.
컴파일 최적화
내가 만난 많은 VB 프로그래머들은 컴파일 옵션을 사용해본 적도 없고 옵션 간의 차이점을 알아내려고 노력한 적도 없습니다. 각 옵션의 구체적인 의미를 살펴보겠습니다.
1.P 코드(의사 코드) 및 네이티브 코드
소프트웨어를 P 코드 또는 기본 코드로 컴파일하도록 선택할 수 있습니다. 기본 옵션은 네이티브 코드입니다. 그렇다면 P 코드와 네이티브 코드는 무엇입니까?
P 코드: VB에서 코드를 실행할 때 VB는 먼저 코드를 P 코드로 컴파일한 다음 컴파일된 P 코드를 해석하고 실행합니다. 컴파일된 환경에서는 이 코드를 사용하는 것이 네이티브 코드보다 빠릅니다. P-코드를 선택한 후 VB는 컴파일할 때 의사코드를 EXE 파일에 넣습니다.
네이티브 코드: 네이티브 코드는 VB6 이후에만 도입된 옵션입니다. EXE 파일로 컴파일하면 네이티브 코드가 P 코드보다 빠르게 실행됩니다. 기본 코드를 선택한 후 VB는 컴파일할 때 기계 명령어를 사용하여 EXE 파일을 생성합니다.
네이티브 코드로 컴파일할 때 가끔 설명할 수 없는 오류가 발생하는 것을 발견했습니다. 내 코드는 컴파일 환경에서 완전히 올바르게 실행되지만 네이티브 코드 옵션으로 생성된 EXE 파일은 올바르게 실행되지 않습니다. 일반적으로 이는 창이 언로드되거나 인쇄 창이 팝업될 때 발생합니다. 코드에 DoEvent 문을 추가하여 이 문제를 해결했습니다. 물론, 이런 일이 일어날 가능성은 매우 드뭅니다. 아마도 일부 VB 프로그래머는 이런 일을 겪어본 적이 없을 것입니다.
네이티브 코드에는 다음과 같은 몇 가지 옵션도 있습니다.
a) 코드 속도 최적화: 이 옵션은 더 빠른 실행 파일을 컴파일할 수 있지만 실행 파일이 더 큽니다. 추천
b) 코드 크기 최적화: 이 옵션은 더 작은 실행 파일을 컴파일할 수 있지만 속도가 저하되므로 권장되지 않습니다.
c) 최적화 없음: 이 옵션은 최적화 없이 P 코드만 네이티브 코드로 변환합니다. 코드를 디버깅할 때 사용할 수 있습니다.
d) Pentium Pro에 최적화: 네이티브 코드에서는 이 옵션이 기본 옵션은 아니지만 주로 이 옵션을 사용합니다. 이 옵션으로 컴파일된 실행 프로그램은 PentiumPro 및 Pentium2 이상 시스템에서 더 빠르게 실행될 수 있지만 이전 시스템에서는 약간 느려집니다. Pentium2를 사용하는 것이 이제 구식이라는 점을 고려하면 모든 사람이 이 옵션을 사용하는 것이 좋습니다.
e) 기호 디버깅 정보 생성: 이 항목은 컴파일 프로세스 중에 일부 디버깅 정보를 생성하므로 사용자는 Visual C++와 같은 도구를 사용하여 컴파일된 코드를 디버깅할 수 있습니다. 이 옵션을 사용하면 실행 파일에 플래그 정보를 기록하는 .pdf 파일이 생성됩니다. 이 옵션은 프로그램에 API 함수나 DLL 호출이 있을 때 유용합니다.
2. 고급 최적화
고급 최적화의 설정은 소프트웨어 속도를 향상시키는 데 도움이 될 수 있지만 때로는 버그가 발생할 수 있으므로 최대한 주의해서 사용하는 것이 좋습니다. 코드에 상대적으로 큰 루프 본문이 있거나 복잡한 수학 연산이 있는 경우 고급 최적화에서 특정 항목을 선택하면 코드 성능이 크게 향상됩니다. 고급 최적화 기능을 사용하는 경우 컴파일된 파일을 엄격하게 테스트하는 것이 좋습니다.
a) 별칭이 없다고 가정: 루프 본문 내 코드의 실행 효율성을 높일 수 있지만, 메소드 호출 등 변수 참조를 통해 변수 값이 변경되면 변수 참조가 메소드의 매개변수로 사용되며, 메소드에서 변수 값이 변경되면 오류가 발생합니다. 단지 반환된 결과가 잘못되었을 수도 있고, 프로그램이 중단되는 심각한 오류일 수도 있습니다.
b) 배열 바인딩 검사 취소, 정수 오버플로 검사 취소 및 부동 소수점 오류 검사 취소: 프로그램이 실행 중일 때 이러한 검사를 통해 오류가 발견되면 오류 처리 코드가 해당 오류를 처리합니다. 그러나 이러한 검사가 취소되면 프로그램은 오류를 처리할 수 없습니다. 위의 오류가 코드에서 발생하지 않을 것이라고 확신하는 경우에만 이러한 옵션을 사용해야 합니다. 소프트웨어 성능이 크게 향상됩니다.
c) 반올림 없이 부동 소수점 연산 허용: 이 옵션을 선택하면 컴파일된 프로그램이 부동 소수점 연산을 더 빠르게 처리할 수 있습니다. 유일한 단점은 두 개의 부동 소수점 숫자를 비교할 때 잘못된 결과가 발생할 수 있다는 것입니다.
d) PentiumFDIV 보안 검사 취소: 이 옵션은 일부 오래된 Pentium 칩에 대해 설정되어 있으며 현재는 오래된 것 같습니다.