こんなコト気にしなくて良いのでしょうが

がきと今日購入した 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 での研鑽が必要ではないかと (何