#:g1: string-caseの紹介

Posted 2014-01-26 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の27日目です。

string-caseとはなにか

 string-caseは、Paul-Virak Khuong氏作の文字列に対するcaseです。

パッケージ情報

パッケージ名string-case
Quicklisp
参考サイトhttp://pvk.ca/string-case.lisp
Quickdocshttp://quickdocs.org/string-case

インストール方法

(ql:quickload :string-case)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 Common Lispでは、caseでの判定はEQLを利用している為、文字列の比較ができないというのはFAQです。
その為、大抵のユーティリティには、今回紹介するstring-caseのようなものが含まれていますが、string-caseは通常のstring=での比較よりも高速な方法を採用しています。
とはいえ、実装が高速なだけで、使い方は普通です。

(let ((x "foo"))
  (string-case:string-case (x)
    ("foo" :win)
    ("fooo" :lose)))
;=>  :WIN

 上記のマクロは、下記のように展開されます

(LET ((#:INPUT3171 "foo"))
  (FLET ((#:ON-ERROR3172 ()
           (ERROR "No match")))
    (LOCALLY
     (DECLARE (TYPE VECTOR #:INPUT3171))
     (CASE (LENGTH #:INPUT3171)
       ((3)
        (LOCALLY
         (DECLARE
          (TYPE (OR (NOT SIMPLE-ARRAY) (SIMPLE-ARRAY * (3))) #:INPUT3171))
         (IF (AND
              (ZEROP
               (LOGIOR (STRING-CASE::NUMERIC-CHAR= #f (AREF #:INPUT3171 0))
                       (STRING-CASE::NUMERIC-CHAR= #o (AREF #:INPUT3171 1))
                       (STRING-CASE::NUMERIC-CHAR= #o (AREF #:INPUT3171 2)))))
             (PROGN :WIN)
             (#:ON-ERROR3172))))
       ((4)
        (LOCALLY
         (DECLARE
          (TYPE (OR (NOT SIMPLE-ARRAY) (SIMPLE-ARRAY * (4))) #:INPUT3171))
         (IF (AND
              (ZEROP
               (LOGIOR (STRING-CASE::NUMERIC-CHAR= #f (AREF #:INPUT3171 0))
                       (STRING-CASE::NUMERIC-CHAR= #o (AREF #:INPUT3171 1))
                       (STRING-CASE::NUMERIC-CHAR= #o (AREF #:INPUT3171 2))
                       (STRING-CASE::NUMERIC-CHAR= #o (AREF #:INPUT3171 3)))))
             (PROGN :WIN)
             (#:ON-ERROR3172))))
       (T (#:ON-ERROR3172))))))

string=の比較ではなく、探索木を作成し、その上で高速なnumeric-char=で比較します。
さらに、SBCLの場合は、numeric-char=がVOPというアセンブリレベルの記述を用いて書かれていて、さらなる高速化が図られています。

string-caseの紹介/関連記事等

まとめ

 今回は、string-caseを紹介してみました。
SBCLでVOPを使って高速化しているコードというのは、あまり多く目にすることはないと思うので参考になるのではないかと思います。

comments powered by Disqus