루비의 메모이제이션

Memoization은 모든 Ruby 개발자가 완벽하게 사용해야 하는 간단하고 강력한 성능 최적화 기술입니다.
여기서는 난이도가 높아지는 순서대로 세 가지 메모이제이션 변형을 살펴보겠습니다.
  • 나이브||= 기반 메모제이션
  • 중급 defined? 기반 메모이제이션
  • 매개 변수가 있는 방법에 대한 고급 메모화

  • 1. ||=



    왼쪽이 false인 경우에만 할당이 발생하는 "or-equals"로 발음되는 인기 있는 Ruby 관용구입니다. 잠재적으로 할당된 값이 절대 거짓이 아님을 알고 있는 경우 이를 사용하십시오.

    def response
      # it is a common practice to store the memoized value in
      # an instance variable (ivar) of the same name as the method.
      @response ||= expensive_operation
    end
    


    2. 정의? 기반 메모이제이션



    잘못된 값을 기억할 수 있는 잘 알려지지 않은 패턴입니다. expensive_operation가 여러 줄 문인 경우에도 유용합니다.

    def response
      return @response if defined?(@response)
    
      # NB, this is a regular assignment because line above already did the cache check.
      @response = expensive_operation
    end
    


    3. 매개변수가 있는 메소드의 메모이제이션



    메서드에 지정된 인수에 따라 여러 값을 메모하는 것이 유용한 경우가 있습니다. 이 접근 방식은 메서드가 반환하는 값(및 메모할 값)이 idempotent인 경우에만 사용할 수 있습니다. 즉, 반복 호출에서 동일하게 유지됩니다.
    memo_key는 주어진 인수에 따라 고유해야 합니다. Object#hash를 사용하는 것이 일반적인 접근 방식이지만 다른 방법도 있을 수 있습니다. 예를 들어 args는 알려진 유형일 수 있고 .id에서 반환된 고유 식별자를 가질 수 있습니다.

    def response(arg1, arg2)
      @memo ||= {}
      memo_key = "#{arg1.hash}_#{arg2.hash}"
    
      return @memo[memo_key] if @memo.key?(memo_key)
    
      @memo[memo_key] = begin
        puts "Doing expensive operation"
        expensive_operation
      end
    end
    
    > response(:a, :b)
    Doing expensive operation
    => something
    > response(:a, :b)
    => something
    
    > response(false, false)
    Doing expensive operation
    => something_else
    > response(false, false)
    => something_else
    

    좋은 웹페이지 즐겨찾기