임시 변수가 내 프로그램을 느리게합니까?
다음 C 코드가 있다고 가정합니다.
int i = 5;
int j = 10;
int result = i + j;
이것을 여러 번 반복하면 사용하는 것이 더 빠를 int result = 5 + 10
까요? 예를 들어, 인덱스를 계산하기 위해 긴 표현식을 사용하여 일부 배열에서 두 변수를 얻은 경우 코드를 더 읽기 쉽게 만들기 위해 임시 변수를 자주 만듭니다. C에서 성능이 좋지 않습니까? 다른 언어는 어떻습니까?
우리가 다음 예제를 사용하는 경우 현대 최적화 컴파일러는 예를 들어, 멀리 그 변수를 최적화해야 godbolt 와 gcc
사용하여 -std=c99 -O3
플래그를 ( 이 살고 참조 )
#include <stdio.h>
void func()
{
int i = 5;
int j = 10;
int result = i + j;
printf( "%d\n", result ) ;
}
다음 어셈블리가 생성됩니다.
movl $15, %esi
계산을 위해 i + j
이것은 일정한 전파의 형태입니다 .
참고로, printf
부작용이 있도록를 추가했습니다 . 그렇지 않으면 func
다음과 같이 최적화되었을 것입니다.
func:
rep ret
이러한 최적화는 as-if 규칙 하에서 허용 되며 컴파일러가 프로그램의 관찰 가능한 동작을 에뮬레이트하기 만하면됩니다. 이것은 C99 표준 초안 섹션 5.1.2.3
프로그램 실행 에서 다룹니다 .
추상 기계에서 모든 표현식은 의미 체계에 지정된대로 평가됩니다. 실제 구현은 해당 값이 사용되지 않고 필요한 부작용이 발생하지 않는다고 추론 할 수있는 경우 표현식의 일부를 평가할 필요가 없습니다 (함수를 호출하거나 휘발성 개체에 액세스하여 발생하는 결과 포함).
참조 : C ++ 코드 최적화 : 상수 접기
이것은 최적화 컴파일러를 위해 최적화하는 쉬운 작업입니다. 모든 변수를 삭제 result
하고 15
.
SSA 형식의 상수 접기 는 가장 기본적인 최적화입니다.
여러분이 제공 한 예제는 컴파일러가 최적화하기 쉽습니다. 지역 변수를 사용하여 전역 구조 및 배열에서 가져온 값을 캐시하면 실제로 코드 실행 속도를 높일 수 있습니다. 예를 들어 컴파일러가 최적화 할 수없고 값이 변경되지 않는다는 것을 알고있는 for 루프 내부의 복잡한 구조에서 무언가를 가져 오는 경우 로컬 변수는 상당한 시간을 절약 할 수 있습니다.
GCC (다른 컴파일러도 포함)를 사용하여 중간 어셈블리 코드를 생성하고 컴파일러가 실제로 수행하는 작업을 볼 수 있습니다.
여기에서 어셈블리 목록을 켜는 방법에 대한 논의가 있습니다. GCC를 사용하여 읽을 수있는 어셈블리를 생성 하시겠습니까?
생성 된 코드를 검사하고 컴파일러가 실제로 수행하는 작업을 확인하는 것이 도움이 될 수 있습니다.
코드에 대한 모든 사소한 차이가 성능을 약간 향상 시키거나 악화시키는 방식으로 컴파일러의 동작을 교란시킬 수 있지만 원칙적으로 프로그램의 의미가 아닌 한 이와 같은 임시 변수를 사용하더라도 성능 차이를 만들지 않아야합니다. 변경되었습니다. 좋은 컴파일러는 소스에 가능한 한 가까운 (예 : 디버깅 목적으로) 기계 코드를 얻기 위해 의도적으로 최적화를 해제 한 상태로 빌드하지 않는 한, 어느 쪽이든 동일하거나 유사한 코드를 생성해야합니다.
컴파일러가 무엇을하는지 배우려고 할 때와 똑같은 문제를 겪고 있습니다. 문제를 설명하기 위해 사소한 프로그램을 만들고 컴파일러의 어셈블리 출력을 검사하여 컴파일러가 모든 것을 최적화했다는 것을 깨닫습니다. 당신은 그것을 없애려고 노력했습니다. main ()에서 다소 복잡한 연산이 본질적으로 축소 된 것을 찾을 수 있습니다.
push "%i"
push 42
call printf
ret
원래 질문은 "어떻게 int i = 5; int j = 10...
되나요?" 가 아닙니다. 그러나 "임시 변수는 일반적으로 런타임 패널티를 초래합니까?"
대답은 아마 아닐 것입니다. 그러나 특정하고 사소하지 않은 코드에 대한 어셈블리 출력을 확인해야합니다. CPU에 ARM과 같은 많은 레지스터가있는 경우 i와 j는 레지스터에있을 가능성이 매우 높습니다. 마치 해당 레지스터가 함수의 반환 값을 직접 저장하는 것과 같습니다. 예를 들면 :
int i = func1();
int j = func2();
int result = i + j;
is almost certainly to be exactly the same machine code as:
int result = func1() + func2();
I suggest you use temporary variables if they make the code easier to understand and maintain, and if you're really trying to tighten a loop, you'll be looking into the assembly output anyway to figure out how to finesse as much performance out as possible. But don't sacrifice readability and maintainability for a few nanoseconds, if that's not necessary.
참고URL : https://stackoverflow.com/questions/26949569/do-temp-variables-slow-down-my-program
'Development Tip' 카테고리의 다른 글
파이썬을 사용하여 파일에서 한 번에 두 줄을 읽는 방법 (0) | 2020.10.26 |
---|---|
일부 패턴을 제외하고 grep하는 방법? (0) | 2020.10.26 |
중괄호가있는 Javascript (ES6) const (0) | 2020.10.26 |
숫자를 포함 할 수있는 문자열을 기준으로 정렬 (0) | 2020.10.26 |
JavaScript에서 이름 문자열로 동적으로 전역 변수 가져 오기 (0) | 2020.10.26 |