こんなコト気にしなくて良いのでしょうが
がきと今日購入した algo というゲームをヤッて頭に限界を感じてたりしつつ一服してて vm 的にどっちが効率が良いのか、が気になったりなんかして。
何のコトか
とゆーと今日の
(define (snmp-port-check l) (if (null? l) #f (match (string-split (car l) char-whitespace?) ((_ _ _ "127.0.0.1:161" _ _) #t) (else (snmp-port-check (cdr l))))))
と
(define (port-check) (rxmatch #/:161 / (process-output->string '(netstat -n --all))))
の処理効率。って、これは比較にならんな。
(define (port-check) (let f ((l (process-output->string-list '(netstat -n --all)))) (match l ((x . _) (rxmatch-if (rxmatch #/:161 / x) () #t (f (cdr l)))) (else #f))))
ええと比較するとしたら以下の式と
(if (null? l) #f (match (string-split (car l) char-whitespace?) ((_ _ _ "127.0.0.1:161" _ _) #t) (else (snmp-port-check (cdr l)))))
以下の式?
(match l ((x . _) (rxmatch-if (rxmatch #/:161 / x) () #t (f (cdr l)))) (else #f))
というコトで試してみます。
gosh> (disasm (lambda (l) (if (null? l) #f (match (string-split (car l) char-whitespace?) ((_ _ _ "127.0.0.1:161" _ _) #t) (else (snmp-port-check (cdr l))))) )) main_code (name=#f, code=0x8185da8, size=44, const=11, stack=26): args: #f 0 LREF0 ; l 1 BNNULL 4 ; (null? l) 3 CONSTF-RET 4 PRE-CALL(2) 12 6 LREF0 ; l 7 CAR-PUSH ; (car l) 8 GREF-PUSH #<identifier user#char-whitespace?>; char-whitespace? 10 GREF-CALL(2) #<identifier user#string-split>; (string-split (car l) char-whitespace?) 12 PUSH-PRE-CALL(1) 31 14 CONST-PUSH #t 16 PRE-CALL(5) 30 18 GREF-PUSH #<identifier user#_>; _ 20 GREF-PUSH #<identifier user#_>; _ 22 CONST-PUSH "127.0.0.1:161" 24 GREF-PUSH #<identifier user#_>; _ 26 GREF-PUSH #<identifier user#_>; _ 28 GREF-CALL(5) #<identifier user#_>; (_ _ _ "127.0.0.1:161" _ _) 30 CALL(1) ; ((_ _ _ "127.0.0.1:161" _ _) #t) 31 PUSH-PRE-CALL(1) 41 33 PRE-CALL(1) 39 35 LREF0 ; l 36 CDR-PUSH ; (cdr l) 37 GREF-CALL(1) #<identifier user#snmp-port-check>; (snmp-port-check (cdr l)) 39 PUSH-GREF-CALL(1) #<identifier user#else>; (else (snmp-port-check (cdr l))) 41 PUSH-GREF-TAIL-CALL(3) #<identifier user#match>; (match (string-split (car l) char-whites ... 43 RET #<undef> gosh>
もう一つ。
gosh> (disasm (lambda (l) (match l ((x . _) (rxmatch-if (rxmatch #/:161 / x) () #t (f (cdr l)))) (else #f)) )) *** ERROR: Compile Error: proper list required for function application or macro use: (x . _) "(stdin)":16:(disasm (lambda (l) (match l ((x . _ ... Stack Trace: _______________________________________ gosh>
ええとなんだっけ。util.match か。
gosh> (use util.match) #<undef> gosh> (disasm (lambda (l) (match l ((x . _) (rxmatch-if (rxmatch #/:161 / x) () #t (f (cdr l)))) (else #f)) )) main_code (name=#f, code=0x813d0e0, size=25, const=3, stack=16): args: #f 0 LREF0 ; l 1 PAIRP ; (pair? l) 2 BF 24 ; (if (pair? l) ((lambda (x) (rxmatch-if ( ... 4 LREF0 ; l 5 CAR-PUSH ; (car l) 6 LOCAL-ENV(1) ; ((lambda (x) (rxmatch-if (rxmatch #/:161 ... 7 PRE-CALL(2) 13 9 CONST-PUSH #/:161 / 11 LREF0-PUSH-GREF-CALL(2) #<identifier user#rxmatch>; (rxmatch #/:161 / x) 13 PUSH-LOCAL-ENV(1) ; ((rxmatch #/:161 / x) => (lambda (match) ... 14 LREF0 ; tmp 15 BF 19 ; ((rxmatch #/:161 / x) => (lambda (match) ... 17 CONST-RET #t 19 LREF20 ; l 20 CDR-PUSH ; (cdr l) 21 GREF-TAIL-CALL(1) #<identifier user#f>; (f (cdr l)) 23 RET 24 CONSTF-RET #<undef> gosh>
うーん。ちょっとヤリ方微妙みたい。名前付き let とかで云々、かなぁ。
リトライ
まず一発目
gosh> (disasm (lambda (l) (let snmp-port-check ((l l)) (if (null? l) #f (match (string-split (car l) char-whitespace?) ((_ _ _ "127.0.0.1:161" _ _) #t) (else (snmp-port-check (cdr l))))) ))) main_code (name=#f, code=0x80d7d98, size=6, const=1, stack=8): args: #f 0 LOCAL-ENV-CLOSURES(1) (#<lambda 0>); (let snmp-port-check ((l l)) (if (null? ... 2 LREF10-PUSH ; l 3 LREF0 ; snmp-port-check 4 LOCAL-ENV-TAIL-CALL(1) 5 RET internal_closure_0 (name=snmp-port-check, code=0x814ff18, size=44, const=10 stack=26): args: #f 0 LREF0 ; l 1 BNNULL 4 ; (null? l) 3 CONSTF-RET 4 PRE-CALL(2) 12 6 LREF0 ; l 7 CAR-PUSH ; (car l) 8 GREF-PUSH #<identifier user#char-whitespace?>; char-whitespace? 10 GREF-CALL(2) #<identifier user#string-split>; (string-split (car l) char-whitespace?) 12 PUSH-PRE-CALL(1) 31 14 CONST-PUSH #t 16 PRE-CALL(5) 30 18 GREF-PUSH #<identifier user#_>; _ 20 GREF-PUSH #<identifier user#_>; _ 22 CONST-PUSH "127.0.0.1:161" 24 GREF-PUSH #<identifier user#_>; _ 26 GREF-PUSH #<identifier user#_>; _ 28 GREF-CALL(5) #<identifier user#_>; (_ _ _ "127.0.0.1:161" _ _) 30 CALL(1) ; ((_ _ _ "127.0.0.1:161" _ _) #t) 31 PUSH-PRE-CALL(1) 41 33 PRE-CALL(1) 39 35 LREF0 ; l 36 CDR-PUSH ; (cdr l) 37 LREF10 ; snmp-port-check 38 LOCAL-ENV-CALL(1) ; (snmp-port-check (cdr l)) 39 PUSH-GREF-CALL(1) #<identifier user#else>; (else (snmp-port-check (cdr l))) 41 PUSH-GREF-TAIL-CALL(3) #<identifier user#match>; (match (string-split (car l) char-whites ... 43 RET gosh>
微妙。ってかなんだかワケワカだよ。もひとつ
gosh> (use util.match) (disasm (lambda (l) (let f ((l l)) (match l ((x . _) (rxmatch-if (rxmatch #/:161 / x) () #t (f (cdr l)))) (else #f)) )) ) gosh> main_code (name=#f, code=0x80d7948, size=6, const=1, stack=8): args: #f 0 LOCAL-ENV-CLOSURES(1) (#<lambda 0>); (let f ((l l)) (match l ((x . _) (rxmatc ... 2 LREF10-PUSH ; l 3 LREF0 ; f 4 LOCAL-ENV-TAIL-CALL(1) 5 RET internal_closure_0 (name=f, code=0x813eb60, size=25, const=2 stack=16): args: #f 0 LREF0 ; l 1 PAIRP ; (pair? l) 2 BF 24 ; (if (pair? l) ((lambda (x) (rxmatch-if ( ... 4 LREF0 ; l 5 CAR-PUSH ; (car l) 6 LOCAL-ENV(1) ; ((lambda (x) (rxmatch-if (rxmatch #/:161 ... 7 PRE-CALL(2) 13 9 CONST-PUSH #/:161 / 11 LREF0-PUSH-GREF-CALL(2) #<identifier user#rxmatch>; (rxmatch #/:161 / x) 13 PUSH-LOCAL-ENV(1) ; ((rxmatch #/:161 / x) => (lambda (match) ... 14 LREF0 ; tmp 15 BF 19 ; ((rxmatch #/:161 / x) => (lambda (match) ... 17 CONST-RET #t 19 LREF20 ; l 20 CDR-PUSH ; (cdr l) 21 LREF30 ; f 22 LOCAL-ENV-TAIL-CALL(1) ; (f (cdr l)) 23 RET 24 CONSTF-RET gosh>
上記が正しいかどうか、が微妙なんですがもし正しいとしたら vm の命令の行数的にはある程度の改善がなされていると見る事は可能かな、と。
このあたりの理解が微妙なまま、こうしたトライは微妙だなぁ。ReadingGauche での研鑽が必要ではないかと (何