루프 뒤 또는 루프 내부에서 변수를 선언하시겠습니까?

 
   string st = "" ;
   for ( int i = 0 ; i < 1000 ; i++)
   {
      st = i;
      ...
   }

또는

   for ( int i = 0 ; i < 1000 ; i++)
   {
       string st = i;
      ...
   }

차이가 있습니까? 모든 mql5 컴파일러 최적화를 고려합니까?

 
pivalexander :

또는

차이가 있습니까? 모든 mql5 컴파일러 최적화를 고려합니까?

컴파일에는 차이가 없으므로 두 번째 옵션을 자유롭게 사용하십시오.
 

개인적으로 나는 첫 번째 것을 선호합니다.

만약을 위해. 컴파일러는 매번 메모리를 할당하지 않을 만큼 충분히 똑똑할 수 있지만 첫 번째 경우에는 명시적으로 지정하지만 두 번째 경우에는 컴파일러 작업의 암묵적인 결과입니다. 왜냐하면 언어의 논리에 따르면, 변수는 반드시 블록 내부에 생성되어야 하며, 블록에서 나갈 때는 반드시 제거해야 합니다.

음, 변환 없이 int를 string과 동일시하는 것은 나쁜 습관입니다.

 
pivalexander :

차이가 있습니까? 모든 mql5 컴파일러 최적화를 고려합니까?

차이가 없다는 말을 듣지 마십시오. 첫 번째 옵션만 사용하면 차이가 있습니다. 나는 microcl에서 disassm을 공부하지 않았지만.

 
Georgiy Merts :

개인적으로 나는 첫 번째 것을 선호합니다.

만약을 위해. 컴파일러는 매번 메모리를 할당하지 않을 만큼 충분히 똑똑할 수 있지만 첫 번째 경우에는 명시적으로 지정하지만 두 번째 경우에는 컴파일러 작업의 암묵적인 결과입니다. 왜냐하면 언어의 논리에 따르면, 변수는 반드시 블록 내부에 생성되어야 하며, 블록에서 나갈 때는 반드시 제거해야 합니다.

음, 변환 없이 int를 string과 동일시하는 것은 나쁜 습관입니다.

조지의 말이 맞아요, 보장되지는 않습니다.

그리고 우리는 '숫자'에서 '문자열'로의 암시적 변환 경고를 받습니다.


그리고 이것이 바로 우리가 불확실성과 경고를 제거하는 방법입니다

 for ( int i = 0 ; i < 1000 ; i++)
   {
       static string st = IntegerToString (i);
      ...
   }
 
Georgiy Merts :

개인적으로 나는 첫 번째 것을 선호합니다.

만일을 위해. 컴파일러는 매번 메모리를 할당하지 않을 만큼 충분히 똑똑할 수 있지만, 첫 번째 경우에는 이것을 명시적으로 나타내지만 두 번째 경우에는 컴파일러의 암시적 결과입니다.

장난해? 이것은 컴파일러에게 너무 사소한 상황이므로 여기에서 말할 것도 없습니다. 그리고 그런 편집증으로 순전히 어셈블러에서 인코딩할 수 있습니다.) 비록 이것이 지금 현재로서는 이미 무의미해지고 있지만. 최신 컴파일러의 최적화를 능가하려면 매우 열심히 노력해야 합니다.

ps 아마도 나는 이 경우의 사소함에 약간 흥분했을 것입니다. 우리는 문자열 버퍼 에 대해 이야기하고 있습니다. 그러나 MQL에 저장되는 것은 보장됩니다. 루프 내부뿐만 아니라 함수 호출 사이에도 마찬가지입니다. 이 주제는 여기에서 여러 번 논의되었습니다.
 

듣지 마세요, 그들이 여기에서 당신에게 말할 것입니다))

 // c++
#include <iostream>
#include < string >
using namespace std;

void * operator new (size_t sz) {
     void *ptr = std::malloc(sz);
     if (ptr)
         return ptr;
     else
         throw std::bad_alloc{};
}


int main() {
         for ( uint i = 0 ;  i < 3 ;  ++ i) {
                 string s;
                 char buf[ 10 ];
                sprintf(buf, "%u" , i);
                s = "sfjhidfsrtea111" ;
                s += buf;
                cout << s << '\n' ;
        }
}

gcc -O3를 컴파일하고 디버거에서 실행하고 new operator 에 중단점 을 놓고 세 번 호출합니다. 클랜도 마찬가지.

추신: 문자열이 한 주기 동안 제거되면 호출은 하나입니다.

 
Alexey Navoykov :

장난해? 이것은 컴파일러에게 너무 사소한 상황이므로 여기에서 말할 것도 없습니다. 그리고 그런 편집증으로 순전히 어셈블러에서 인코딩할 수 있습니다.) 비록 이것이 지금 현재로서는 이미 무의미해지고 있지만. 최신 컴파일러의 최적화를 능가하려면 매우 열심히 노력해야 합니다.

ps 아마도 나는 이 경우의 사소함에 약간 흥분했을 것입니다. 우리는 문자열 버퍼 에 대해 이야기하고 있습니다. 그러나 MQL에 저장되는 것은 보장됩니다. 루프 내부뿐만 아니라 함수 호출 사이에도 마찬가지입니다. 이 주제는 여기에서 여러 번 논의되었습니다.

아니요. 농담이 아냐.

물론 이 경우 일반 컴파일러는 루프 내에서 변수 선언을 제거해야 합니다.

나는 단지 "컴파일러에 대한 희망이지만 스스로 실수하지 마십시오."라고 생각합니다. 컴파일러 표준에서는 지역 변수가 선언 시 생성되고 선언된 블록이 종료되면 삭제된다고 가정합니다. 따라서 이 원칙은 처음부터 안내되어야 하며 컴파일러가 코드를 개선할 때까지 기다리지 않아야 합니다.

여기서 우리는 효율성(현대 컴파일러는 실제로 매우 높은 품질의 코드를 제공함)이 아니라 프로그래머 자신의 "사고 방식"에 대해 이야기하고 있습니다. Codebase의 소스 코드를 보면, 작고 단순하지만 잠재적으로 위험한 결점이 얼마나 많이 포함되어 있는지 종종 놀라곤 합니다. 이 경우 - 여전히 그다지 중요하지 않고 발생할 수 있는 최대값 - 프로그램이 약간 느리게 실행됩니다. 실제 실수는 훨씬 더 미묘합니다.

 
Vict :

듣지 마세요, 그들이 여기에서 당신에게 말할 것입니다))

gcc -O3를 컴파일하고 디버거에서 실행하고 new operator에 중단점을 설정하고 세 번 호출합니다. 클랜도 마찬가지.

추신: 문자열이 한 주기 동안 제거되면 호출은 하나입니다.

그리고 그는 달리 할 수 없었습니다. 당신 자신이 중단점으로 최적화를 방해했습니다. 최적화의 본질은 알고리즘의 논리를 변경해서는 안 된다는 것입니다. 따라서 명시적으로 감지하는 것은 불가능합니다. 중단점이 있으면 당연히 컴파일러는 이 코드를 잘라낼 권한이 없습니다. 컴파일러가 중단점 을 뛰어 넘을 수 있다고 가정했습니까? )

최적화는 컴파일된 코드나 성능 측정을 통해서만 감지할 수 있습니다. 그래서 이것이 가장 먼저 할 일입니다. 그리고 진정해)

 
측정 대기 중)
 
Alexey Navoykov :

그리고 그는 달리 할 수 없었습니다. 당신 자신이 중단점으로 최적화를 방해했습니다. 최적화의 본질은 알고리즘의 논리를 변경해서는 안 된다는 것입니다. 따라서 명시적으로 감지하는 것은 불가능합니다. 중단점이 있으면 당연히 컴파일러는 이 코드를 잘라낼 권한이 없습니다. 컴파일러가 중단점을 뛰어 넘을 수 있다고 가정했습니까? )

최적화는 컴파일된 코드나 성능 측정을 통해서만 감지할 수 있습니다. 그래서 이것이 가장 먼저 할 일입니다. 그리고 진정해)

젠장, 글쎄, 이것은 단지 거친 밀도, 논평할 것이 있는 것, 디버거에 대한 완전한 오해입니다.

속도 정보 - 메모리 관리자는 그렇게 멍청하지 않으며 OS에 요청하는 것이 아니라 이전에 할당된 것을 재사용할 수 있습니다. 일반적으로 원하는 대로 사용하십시오. 그러나 적어도 강화된 구체적인 증거가 제공될 때까지는 다른 사람들을 설득해서는 안 됩니다. 그들은 어디에 있습니까?