코딩 스타일 정보

 

오랫동안 MQL4로 "처음부터" 작성된 내용을 코딩하고 트랜스코딩해 본 경험이 있어 주제를 제기하고 그 경험을 공유하고 싶습니다.

동료, 특정 알고리즘을 구현하는 프로그램을 빠르게 작성할 수 있는 당신의 능력을 의심하지 않습니다. 그러나 나는 이미 당신이 어떤 이유로 프로젝트를 포기하고 한 달 후에 다시 돌아와서 즉시 이해할 수 없다면 나쁘게 작성한다는 것을 이미 확인했습니다. 다음으로, 내가 직접 개발한 코드 디자인 스타일에 대한 요구 사항을 설정합니다. 제 생각에는 이러한 요구 사항을 준수하면 추가 수정이 크게 단순화됩니다.

0. 서두르지 말고 곧바로 전투에 뛰어들고 프로그램을 작성한다. 고전이 권장하는 대로 하십시오. 프로그램의 구조에 대해 몇 시간 동안 생각하십시오. 그런 다음 앉아서 명확하고 간결한 프로그램을 빠르게 작성할 수 있습니다. 이 몇 시간은 여러 번 작성하고 추가 디버깅하는 속도로 대가를 치르게 될 것입니다.

1. 기능의 길이는 20줄을 크게 초과하지 않아야 합니다. 이것을 구현할 수 없다면 어딘가에 코드의 논리와 구조를 충분히 생각하지 못한 곳이 있습니다. 더욱이, 코드를 디버깅할 때 종종 가장 많은 시간이 소요되는 것은 가장 긴 함수 및 이들에 의해 호출된 함수와의 관계입니다.

예를 들어, 지금 내 코드는 629줄이고 27개의 기능을 가지고 있습니다. 이것은 함수 호출의 구조에 대한 설명(2-6줄)과 각 함수 앞에 간단한 설명, 함수 사이에 4-5줄의 빈 구분 기호가 있습니다. 또한 제한 없이 블록 괄호(중괄호)를 넣습니다. 두 대괄호 각각에 대해 선을 긋습니다. 함수 앞의 모든 주석을 제거하고 함수 사이의 구분 기호 수를 줄이면 27개 함수에 대해 약 400줄이 남게 됩니다. 내 평균 기능 길이는 약 15줄입니다.

물론 이 규칙에는 예외가 있습니다. 그러나 이것은 가장 단순한 함수나 출력 함수에 적용됩니다. 일반적으로 말하면, 기능은 기능적으로 구별되는 작업을 3-5개 이하로 수행해야 합니다. 그렇지 않으면 혼란스러울 것입니다. 함수 내에서 기능적으로 다른 작업 사이에는 일반적으로 빈 줄도 넣습니다.

나는 4개(최소값, 함수 본문에 한 줄, 선언 줄당 하나, 중괄호당 두 줄)에서 10줄에 이르는 꽤 많은 함수를 가지고 있습니다. 나는 이것 때문에 코드 속도 감소에 대해 걱정하지 않는다. 왜냐하면 실제로 코드 속도가 느려지는 것은 이것 때문이 아니라 비뚤어진 손 때문입니다.

2. 액션의 의미, 변수, 기능의 의미를 설명하는 댓글에 인색하지 마세요. 함수 길이의 20줄 제한은 흔들리지 않습니다. 그래도 깨지면 함수를 다시 작성하십시오. 주석은 한 줄 또는 여러 줄일 수 있습니다.

3. 내 기능은 구조화되어 있습니다. 가장 높은(제로) 호출 수준, 1st, 2nd 등의 기능이 있습니다. 다음 호출 수준의 각 함수는 이전 수준의 함수에 의해 직접 호출됩니다. 예를 들어 다음과 같은 기능이 있습니다.

// open
// .pairsToOpen
// .combineAndVerify( )
// Собирает из двух валют символ и выполняет все проверки, нужные для его открытия.
// Возвращает валидность пары для открытия.
// Последний аргумент - [...]
bool
combineAndVerify ( string quoted, string base, double& fp1 )

- 3단계 기능입니다. 여기:

open() - 첫 번째 수준 함수,

pairsToOpen() - 두 번째(open() 함수에 의해 호출됨),

CombineAndVerify()는 세 번째 것입니다(pairsToOpen() 함수에 의해 호출됨).


내가 가지고 있는 다음 수준의 각 기능 코드는 이전 기능의 코드보다 왼쪽 가장자리에서 더 들여쓰기되어 있습니다. 이렇게 하면 전체 프로그램의 구조를 더 잘 볼 수 있습니다.

이 규칙에 대한 예외도 있지만(더 높은 구조 수준의 두 함수에 의해 호출되는 함수가 있음) 드문 경우입니다. 이것은 일반적으로 코드가 최적이 아님을 나타냅니다. 동일한 작업이 프로그램의 여러 다른 부분에서 수행됩니다.
그러나 어디에서나 호출할 수 있는 범용 함수가 있습니다. 이것들은 추론 기능입니다. 저는 그것들을 특별한 범주에 넣었습니다.

3. 전역 변수 : 적은 수를 갖는 것이 좋지만 여기에서는 과도하게 사용하지 않는 것이 좋습니다. 그러한 모든 변수를 함수의 형식 매개변수에 밀어넣는 것은 가능하지만, 그 호출은 쓰기가 너무 번거롭고 의미가 모호합니다.

4. 별도의 계산 및 출력 작업(파일, 화면 또는 SMS로). 모든 출력 함수를 별도로 작성한 다음 이러한 함수에 대한 호출을 호출하는 함수의 본문에 삽입합니다.

이 규칙은 코드의 명확성과 가독성을 향상시키는 것 외에도 또 다른 부작용이 있습니다. 이렇게 하면 코드의 모든 출력을 매우 쉽게 잘라낼 수 있고 코드 실행 시간을 크게 줄일 수 있습니다. 프로그램에서 가장 느린 동작.

5. 변수의 이름: 글쎄요, 여기서 모든 것이 명확합니다. 사람마다 스타일이 있지만 변수의 의미를 쉽게 설명할 수 있도록 만드는 것이 바람직합니다.

시작하기에 충분하다고 생각합니다. 원하는 사람은 다른 것을 추가할 수 있습니다.
 
 
Mathemat >> :
시작하기에 충분하다고 생각합니다. 원하는 사람은 다른 것을 추가할 수 있습니다.

질문은 ~이야. 프로그램을 만드는 가장 좋은 방법은 무엇입니까?

1. START 기능에서 가능한 모든 것을 설명하시겠습니까?

2. 또는 모든 작업을 사용자 정의 함수로 작성한 다음 필요에 따라 START 함수에서 호출하시겠습니까?

//------------------------------------------------ ----

예를 들어, 같은 트롤.

 

두 번째가 더 좋습니다. 나는 이것에 대해 쓰고 있습니다. 거래 기능 을 별도의 기능으로 작성하는 것도 바람직합니다.

 

나는 거의 모든 것을 가지고 있습니다.

제외한:

1. 함수의 줄 수.

2. 기능의 수.

내 우선 순위는 속도입니다. 따라서 함수가 적고 호출 횟수가 적을수록 프로그램이 더 빠르게 실행됩니다.

기능을 없앨 기회가 있으면 이 기회를 이용합니다.

한 번만 실패했습니다. 메타쿼타는 중첩 블록 수에 제한을 가했습니다.

그 결과 710줄의 인터페이스를 그리는 기능이 생겼습니다. 51개의 매개변수가 있습니다. 이 중 21개의 어레이가 있습니다. 그것이 Metaquotes가 가져온 것입니다 ... :-)))

일반적으로 함수는 프로그램의 다른 부분에서 호출되는 경우에만 필요하며 자주 사용하지 않는 경우에만 필요하다고 생각합니다. 속도를 위해 각 블록에서 코드를 반복하는 것을 선호합니다.

 
Zhunko >> :

그 결과 710줄의 인터페이스를 그리는 기능이 생겼습니다. 51개의 매개변수가 있습니다. 이 중 21개의 어레이가 있습니다.

우와. 그러나 이미 언급한 추론 기능은 예외입니다. 실행 속도 면에서는 함수 없이 원하는 블록을 직접 작성하는 대신 함수를 호출하는 오버헤드가 그다지 크지 않은 것 같습니다. 특히 함수가 루프에서 호출되는 경우에는 그렇습니다. 어딘가에서 Rosh는 직접 코드와 함수 호출이 있는 코드의 차이점을 보여주었습니다.

 
Zhunko писал(а) >>

내 우선 순위는 속도입니다. 따라서 함수가 적고 호출 횟수가 적을수록 프로그램이 더 빠르게 실행됩니다.

기능을 없앨 기회가 있으면 이 기회를 이용합니다.

동의한다. 함수가 3회 미만으로 호출되면 본문에 삽입하는 것이 좋습니다. 친숙한 직접. 종종 다른 사람의 프로그램을 편집해야 합니다. 모든 기능이 있으면 언제 무슨 일이 일어날지 혼동하지 않도록 두세 개의 창을 열어야 합니다.

 
Mathemat >> :

우와. 그러나 이미 언급한 추론 기능은 예외입니다. 실행 속도 면에서는 함수 없이 원하는 블록을 직접 작성하는 대신 함수를 호출하는 오버헤드가 그다지 크지 않은 것 같습니다. 특히 함수가 루프에서 호출되는 경우에는 그렇습니다. 어딘가에서 Rosh는 직접 코드와 함수 호출이 있는 코드의 차이점을 보여주었습니다.

Alexei, 아마도 당신이 맞을 것입니다. 나는 최근에 그것을 믿지 않았지만! ...

아마도 그 당시 Metaquotes는 MT4의 메모리 관리자에 문제가 있었습니다. 그래서 인덱스 계산에 사용했던 함수들을 모두 제거하고 결과에 매우 놀랐습니다!... 계산 속도는 5배, 메모리 사용량은 3배 감소!!!

 
Zhunko писал(а) >>

Alexey, 아마도 당신이 맞을 것입니다. 나는 최근에 그것을 믿지 않았지만, 그러나! ...

아마도 그 당시 Metaquotes는 MT4의 메모리 관리자에 문제가 있었습니다. 그래서 인덱스 계산에 사용했던 함수들을 모두 제거하고 결과를 보니 정말 놀랐습니다!... 계산속도는 5배, 메모리 소모는 3배!!!

함수에 선언된 모든 배열은 정적입니다. 이것은 이러한 배열이 한 번만 생성되고(첫 번째 함수 호출 시) 메모리에 저장된다는 것을 의미합니다. 그래서 배열을 전역으로 만들려고 합니다. 좋지 않은 것.

 
함수 크기. 기능을 한 화면에 맞추려고 합니다. 다 볼 수 있도록.
 

예, Vadim , 영향력이 있습니다. 확인하기로 결정했습니다. 결과는 다음과 같습니다.

1. 단순 합산 루프(5억 번 반복):


int start()
{
double sum = 0;
double d;
int st = GetTickCount();
for( int i = 0; i < 500000000; i ++ )
{
add( sum );


// sum += 3.14159265;

}
int timeTotal = GetTickCount() - st;
Print( "Time = " + timeTotal );
return(0);
}
//+------------------------------------------------------------------+


double add( double sum )
{
return( sum + 3.14159265 );
}//+------------------------------------------------------------------+


초 단위 계산 시간: 4.42 - add() 함수를 호출하지 않고 호출하면 36.7.


2. 더 복잡한 계산이 포함된 루프(동일한 5억 번 반복):


int start()
{
double sum = 0;
double d;
int st = GetTickCount();
for( int i = 0; i < 500000000; i ++ )
{
add( i, sum, d );


// d = MathTan( i ) + MathLog( i );
// sum += MathSin( 3.14159265 );
}
int timeTotal = GetTickCount() - st;
Print( "Time = " + timeTotal );
return(0);
}//+------------------------------------------------------------------+


double add( int i, double sum, double& d )
{
d = MathTan( i ) + MathLog( i );
return( sum + MathSin( 3.14159265 ) );
}//+------------------------------------------------------------------+


계산 시간(초): 100.6 - add() 함수를 호출하지 않고 142.1을 호출합니다.


여기에서 루프에서 직접 계산이 포함된 블록은 주석 처리되어 비교를 위해 함수로 형식화됩니다. 보시다시피 경우에 따라 차이가 있지만 매우 다릅니다.

결론은 무엇입니까? 매우 간단한 것을 함수로 래핑하면 함수 호출 비용이 매우 중요한 역할을 합니다. 저것들. 함수 본문의 계산 비용보다 훨씬 더 많을 수 있습니다. 계산이 더 복잡하면 기능의 존재와 부재의 차이가 급격히 감소합니다.

따라서 함수에서는 다소 심각한 계산이 포함된 블록만 정렬하는 것이 좋습니다. 코딩할 때 이 점을 고려해 보겠습니다. 그러나 어쨌든 시간의 차이는 루프에 많은 반복이 있을 때만 중요합니다. 여기서 함수를 호출하는 비용은 약 10^(-7)초로 밝혀졌습니다.