비트 단위 연산을위한 연산자 많이 있습니다
예를 들어 당신이
(logxor bit 1)
를 사용할 수있는 비트가 0 인 경우 비트가 1 및 1
경우이 당신에게 0
을 줄 것이다는 :
물론
(logxor 0 1) ; => 1
(logxor 1 1) ; => 0
당신은 두 번째 인수로 bit
부분을 넣을 수 있습니다 :
(logxor 1 bit)
보너스 :
아마도 당신이 기능을하고 유형 선언을 최적화 할 수 있습니다
(disassemble 'invert)
를 실행 한 후 나는 SBCL에 다음과 같은 결과를 얻었다
(defun invert (bit)
"Inverts a bit"
(declare (type bit bit))
(logxor bit 1))
:
을 WITHOUT 형식 선언 :
0 유형 선언으로
; disassembly for INVERT
; Size: 56 bytes. Origin: #x10059E97FC
; 7FC: 498B4C2460 MOV RCX, [R12+96] ; thread.binding-stack-pointer
; no-arg-parsing entry point
; 801: 48894DF8 MOV [RBP-8], RCX
; 805: BF02000000 MOV EDI, 2
; 80A: 488BD3 MOV RDX, RBX
; 80D: 4883EC18 SUB RSP, 24
; 811: 48896C2408 MOV [RSP+8], RBP
; 816: 488D6C2408 LEA RBP, [RSP+8]
; 81B: B904000000 MOV ECX, 4
; 820: FF1425980B1020 CALL QWORD PTR [#x20100B98] ; TWO-ARG-XOR
; 827: 488B5DF0 MOV RBX, [RBP-16]
; 82B: 488BE5 MOV RSP, RBP
; 82E: F8 CLC
; 82F: 5D POP RBP
; 830: C3 RET
; 831: 0F0B10 BREAK 16 ; Invalid argument count trap
는
; disassembly for INVERT
; Size: 25 bytes. Origin: #x1005767CA9
; A9: 498B4C2460 MOV RCX, [R12+96] ; thread.binding-stack-pointer
; no-arg-parsing entry point
; AE: 48894DF8 MOV [RBP-8], RCX
; B2: 488BD3 MOV RDX, RBX
; B5: 4883F202 XOR RDX, 2
; B9: 488BE5 MOV RSP, RBP
; BC: F8 CLC
; BD: 5D POP RBP
; BE: C3 RET
; BF: 0F0B10 BREAK 16 ; Invalid argument count trap
이 유형 선언이 몇 가지 작업을 저장 한 날 것으로 보인다. 실행하는 동안
Evaluation took:
0.007 seconds of real time
0.005164 seconds of total run time (0.005073 user, 0.000091 system)
71.43% CPU
14,060,029 processor cycles
0 bytes consed
:
(defun invert (bit)
"Inverts a bit"
(declare (type bit bit))
(logxor bit 1))
(defun invert-no-dec (bit)
"Inverts a bit"
(logxor bit 1))
것은 이제 실행 :
(time (loop repeat 1000000 do (invert 1)))
출력
의 차이를 측정하자
(time (loop repeat 1000000 do (invert-no-dec 1)))
01 23,516,
출력은 :
Evaluation took:
0.011 seconds of real time
0.011327 seconds of total run time (0.011279 user, 0.000048 system)
100.00% CPU
25,505,355 processor cycles
0 bytes consed
이 유형 선언이 배 빠른 기능을하게 보인다. invert
을 호출하면 (declaim (inline invert))
을 사용하지 않는 한 성능이 향상 될 수 있습니다.CLHS에서 :
인라인 컴파일러에서 function-names로 명명 된 함수에 대한 인라인 호출을 생성하는 것이 바람직하다고 지정합니다. 즉, 지정된 function-name의 코드는 호출 루틴에 통합되어야하며 프로 시저 호출 대신 "in line"으로 나타나야합니다.
"''invert'를 호출하면 성능이 향상 될 것입니다."-'(declaim (inline invert))'를 사용하여 호출을 인라인 할 수 있습니다. – jkiiski
추가되었습니다! 고맙습니다! :) – tsikov
@tsikov : 감사합니다. logxor는 내가 찾고있는 것이었지만 그 중요성은 누락되었습니다. 내가 할 수있는 지금 가정 '(정의-- 수정 매크로 invertf (&) 인수를 휴식 (람다 (비트) (선언 (타입 비트 비트)) (logxor 비트 1)))' 가 선언 및 인라인을 이용하기 ? – davypough