2017-05-18 2 views
4

문자열에서 흥미로운 속성을 추출하기 위해 문자열에서 작동하는 많은 함수가 있습니다. 이러한 기능의 많은에 의해 호출되는 하나 개의 특정 기능은 매우 비싼 궁극적 값의 테이블을 생성 비싼 함수가 테이블을 돌려 정확히 한 번만 스트링 당 테이블을 생성하도록루아에서 개별 함수 호출 사이의 문자열에 비싼 테이블 계산 캐싱

local function expensive(s) 
    local t = nil 
    return function() 
    if not t then 
     t = {} 
     -- some expensive operations with s which add items to t 
    end 
    return t 
    end 
end 

local function fn1(s) 
    local t = expensive(s) 
    -- some other fast operations using t and s 
end 

local function fn2(s) 
    local t = expensive(s) 
    -- some other fast operations using t and s 
end 

local s1, s2 = 'a', 'b' 
fn1(s1) -- should create the 't' table for s1 
fn1(s2) -- should create the 't' table for s2 
fn2(s1) -- should not create the 't' table again for s1 
fn1(s2) -- should also not create the 't' table again for s2 

가 어떻게 그것을 만들 수 있습니다 두 경우 모두? 차라리 테이블을 지구 환경에 노출시키지 않을 것입니다. 이것은 클로저의 영리한 사용에 의해 달성 될 수 있다고 생각하지만 구조를 충분히 잘 모른다.

답변

1

에고의 대답은 일을 할 것입니다,하지만 cache 표는 전체 파일에 의해 액세스 할 수 있습니다. 그것을 숨기려면 몇 가지 옵션이 있습니다. 첫 번째는 간단한 do/end 블록입니다.

local expensive 
do 
    local cache = {} 
    expensive = function (s) 
     local t = cache[s] 
     if not t then 
     t = {} 
     -- some expensive operations with s which add items to t 
     cache[s] = t 
     end 
     return t 
    end 
end 

다른 하나는 자체 실행 기능입니다.

local expensive = (function() 
    local cache = {} 
    return function (s) 
     local t = cache[s] 
     if not t then 
     t = {} 
     -- some expensive operations with s which add items to t 
     cache[s] = t 
     end 
     return t 
    end 
end)() 

자체 실행 기능을 사용하면 한 번만 expensive 함수 이름을 정의 할 수있는 장점을 가지고 있지만, 할 일/엔드 블록보다 읽기가 조금 어렵다 단점. 그렇지 않으면 그들은 거의 동일합니다.

+0

do ... end 블록은 영리합니다! 그것들은 lua 레퍼런스 매뉴얼에서 비슷한 예제를 가지고 있지만이 경우에는 사용하지 않을 생각이다. – ruser9575ba6f

4
local cache = {} 

local function expensive(s) 
    local t = cache[s] 
    if not t then 
    t = {} 
    -- some expensive operations with s which add items to t 
    cache[s] = t 
    end 
    return t 
end 
+0

이것은 처음에 개발 한 솔루션이지만 캐시가 이상적인 스크립트 환경에 노출되어 있습니다. Jack의 대답은이 문제를 해결하는 두 가지 해결책을 제시합니다. – ruser9575ba6f

+1

'cache'는 글로벌 환경에 없습니다 –

+0

충분히 공정합니다. 스크립트의 환경을 의미합니다. – ruser9575ba6f

2

"memoization"을 사용하여 매개 변수에 따라 함수가 반환 한 값을 캐시 할 수 있습니다. a chapter on it in Programming in Lua을 읽고 작업을 수행하는 memoization 모듈 중 하나 (예 : memoize)를 사용할 수 있습니다.

관련 항목에 대해서는 SO answer도 참조하십시오.