Development Tip

순수 기능의 이점

yourdevel 2020. 10. 8. 19:09
반응형

순수 기능의 이점


오늘 나는 순수한 기능에 대해 읽고 그 사용법과 혼동했습니다.

동일한 입력 세트에 대해 동일한 값 세트를 반환하고 관찰 가능한 부작용이없는 함수는 순수하다고합니다.

예를 들어 strlen()는 순수한 기능 rand()이고은 불순한 기능 입니다.

__attribute__ ((pure)) int fun(int i)
{
    return i*i;
}

int main()
{
    int i=10;
    printf("%d",fun(i));//outputs 100
    return 0;
}

http://ideone.com/33XJU

위의 프로그램은 pure선언 이 없을 때와 같은 방식으로 작동합니다 .

함수를 pure[출력에 변화가없는 경우] 로 선언하면 어떤 이점이 있습니까?


pure 컴파일러에게 함수에 대한 특정 최적화를 수행 할 수 있음을 알려줍니다. 다음과 같은 코드를 상상해보십시오.

for (int i = 0; i < 1000; i++)
{
    printf("%d", fun(10));
}

순수 함수를 사용하면 컴파일러는 fun(10)1000 번이 아니라 한 번만 평가해야한다는 것을 알 수 있습니다 . 복잡한 기능의 경우 큰 승리입니다.


함수가 '순수하다'고 말하면 외부에서 눈에 보이는 부작용이 없음을 보장하는 것입니다 (댓글에서 말했듯이 거짓말을하면 나쁜 일이 발생할 수 있음). 함수가 '순수'하다는 것을 알면 컴파일러에 이점이 있으며,이 지식을 사용하여 특정 최적화를 수행 할 수 있습니다.

다음은 GCC 문서 에서 pure속성 에 대해 말하는 내용입니다 .

순수한

반환 값을 제외하고 많은 함수는 효과가 없으며 반환 값은 매개 변수 및 / 또는 전역 변수에만 의존합니다. 이러한 함수는 산술 연산자처럼 공통 하위 표현식 제거 및 루프 최적화의 대상이 될 수 있습니다. 이러한 함수는 pure 속성으로 선언해야합니다. 예를 들면

          int square (int) __attribute__ ((pure));

Philip의 대답은 이미 함수가 '순수'라는 것을 아는 것이 루프 최적화에 어떻게 도움이 될 수 있는지 보여줍니다.

다음은 일반적인 하위 표현식 제거를위한 것입니다 (주어진 foo것은 순수함).

a = foo (99) * x + y;
b = foo (99) * x + z;

다음이 될 수 있습니다.

_tmp = foo (99) * x;
a = _tmp + y;
b = _tmp + z;

가능한 런타임 이점 외에도 순수 함수는 코드를 읽을 때 추론하기가 훨씬 쉽습니다. 또한 반환 값이 매개 변수의 값에만 의존한다는 것을 알고 있으므로 순수 함수를 테스트하는 것이 훨씬 쉽습니다.


순수하지 않은 기능

int foo(int x, int y) // possible side-effects

순수한 기능의 확장과 같습니다.

int bar(int x, int y) // guaranteed no side-effects

여기에서 명시적인 함수 인수 x, y 외에 우주의 나머지 부분 (또는 컴퓨터가 통신 할 수있는 모든 것)을 암시 적 잠재적 입력으로 가지고 있습니다. 마찬가지로 명시 적 정수 반환 값 외에 컴퓨터에서 쓸 수있는 모든 항목은 암시 적으로 반환 값의 일부입니다.

순수하지 않은 함수보다 순수 함수에 대해 추론하는 것이 훨씬 더 쉬운 이유가 분명해야합니다.


애드온과 마찬가지로 C ++ 11이 constexpr 키워드를 사용하여 내용을 코드화한다는 것을 언급하고 싶습니다. 예:

#include <iostream>
#include <cstring>

constexpr unsigned static_strlen(const char * str, unsigned offset = 0) {
        return (*str == '\0') ? offset : static_strlen(str + 1, offset + 1);
}

constexpr const char * str = "asdfjkl;";

constexpr unsigned len = static_strlen(str); //MUST be evaluated at compile time
//so, for example, this: int arr[len]; is legal, as len is a constant.

int main() {
    std::cout << len << std::endl << std::strlen(str) << std::endl;
    return 0;
}

constexpr 사용에 대한 제한으로 인해 함수가 순수함을 입증 할 수 있습니다. 이렇게하면 컴파일러가보다 적극적으로 최적화하고 (꼬리 재귀를 사용하는지 확인하십시오!) 런타임 대신 컴파일 시간에 함수를 평가할 수 있습니다.

따라서 귀하의 질문에 대답하려면 C ++를 사용하는 경우 (C라고 말했지만 관련이 있음) 순수한 함수를 올바른 스타일로 작성하면 컴파일러가 함수로 모든 종류의 멋진 일을 할 수 있습니다. -)


일반적으로 Pure 함수는 컴파일러가 활용할 수있는 불순한 함수보다 3 가지 장점이 있습니다.

캐싱

Lets say that you have pure function f that is being called 100000 times, since it is deterministic and depends only on its parameters, the compiler can calculate its value once and use it when necessary

Parallelism

Pure functions don't read or write to any shared memory, and therefore can run in separate threads without any unexpected consequence

Passing By Reference

A function f(struct t) gets its argument t by value, and on the other hand, the compiler can pass t by reference to f if it is declared as pure while guaranteeing that the value of t will not change and have performance gains


In addition to the compile time considerations, pure functions can be tested fairly easy: just call them.

No need to construct objects or mock connections to DBs / file system.

참고URL : https://stackoverflow.com/questions/11153796/benefits-of-pure-function

반응형