블랙박스 프로시저
블랙박스 프로시저 (Black-Box)
Racket 컴파일러는 순수 계산을 재배치하거나 제거하는 최적화를 수행해요. 그런데 가끔은 이런 최적화가 방해가 될 때가 있습니다. black-box 함수는 그런 최적화를 억제해 주는 도구예요.
출처: Racket Reference
본문
10.8 블랙박스 프로시저
Racket 프로그램이 컴파일될 때(컴파일 제어와 검사 참고), 컴파일러는 눈에 보이는 효과(visible effect)가 없는 순수 계산을 재배치하거나 제거할 수 있습니다. 컴파일 관점에서, 계산을 수행하는 데 걸리는 시간은 눈에 보이는 효과로 간주되지 않아요. 컴파일러는 계산이 사용하는 메모리(계산이 도달 가능하게 유지하는 값 포함)를, 프로그램의 점근적(asymptotic) 메모리 사용을 늘리지 않는 범위까지만 고려합니다. 하지만 메모리 사용을 줄이는 방향으로 계산을 제거하거나 재배치할 수는 있습니다.
black-box 함수는 추가 오버헤드 없이 이런 최적화 중 상당수를 억제합니다.
(black-box v) → any/c
v : any/c
v를 반환합니다.
Racket 컴파일러가 보기에 black-box는 알 수 없는 값을 반환하고, v와 관련된 부수 효과(side effect)를 가지는 것으로 취급됩니다. 그 말은 black-box 호출이나 그 인자를 컴파일 시간에 제거할 수 없고, 다른 부수 효과와 관련해서 그 평가를 재배치할 수 없다는 뜻이에요.
예시:
> (let ([to-power 100])
(let loop ([i 1000])
(unless (zero? i)
; call to `expt` is optimized away entirely, since
; there's no effect and the result is unused:
(expt 2 to-power)
(loop (sub1 i)))))
> (let ([to-power 100])
(let loop ([i 1000])
(unless (zero? i)
; call to `expt` is optimized to just returning a folded
; constant, instead of calling `expt` each iteration:
(black-box (expt 2 to-power))
(loop (sub1 i)))))
> (let ([to-power (black-box 100)])
(let loop ([i 1000])
(unless (zero? i)
; in safe mode, calls `expt`, because `to-power` is not
; known to be a number; optimized away in unsafe mode:
(expt 2 to-power)
(loop (sub1 i)))))
> (let ([to-power (black-box 100)])
(let loop ([i 1000])
(unless (zero? i)
; arithmetic really performed every iteration, since the
; `to-power` value is assumed unknown, and the `expt`
; result is assumed to be used, even in unsafe mode:
(black-box (expt 2 to-power))
(loop (sub1 i)))))
Added in version 8.18.0.17 of package base.