sbcl

Calling Lisp From C

Cからlispの関数を呼ぶ方法を調べた。 最終的には、lisp環境を動的ライブラリ形式っぽく保存して、Cで作成した実行ファイルから任意の関数を呼び出せるようにしたいのだが(そこまでやるかどうかは分からないが...)、とりあえず今日は、lisp関数を呼び出すCの…

DoubleArray: common lisp用の検索関数

doar-0.0.6のmkdoarコマンドで保存したDoubleArrayデータをロードして検索が行えるcommon lispの関数群を作成して、動かしてみた。検索速度的には、文字列を終始バイト列として扱うことを前提とすれば、C++版に比べて3倍程度遅いだけ(?)なので、まあ許容範囲…

apropos+describe

aproposとdescribeを一緒にしたような関数を作成。 名前はそのままapropos-desc。aproposを使えば、シンボル一覧が取得できるが、それに(そのシンボルにバインドしている)関数などの簡単な情報(引数、返り値、ドキュメント)も一緒に表示されるようにした。基…

read-char高速版?

最近はパーサを書くことが割合多く、そして(僕が書くような)パーサでは、read-char関数の呼び出し部分が、全体の中で一番大きなボトルネックになっていることが少なくない。そういった場合、これまではread-char関数の呼び出し回数を減らす(アルゴリズムやロ…

alpha-char-pの挙動

alpha-char-p関数が自分の予想外の挙動をするのを発見。(確認したのは、sbclとclisp) ;; 予想通り > (alpha-char-p #\a) --> T ;; これも > (alpha-char-p #\0) --> NIL ;; 予想外 > (alpha-char-p #\あ) --> T 別に「アルファベット」が、aからzまでの文字…

メモリ内容出力+stringのメモリ表現

SBCLでマシンコードを直接実行で作成したstring-to-alien-functionマクロを使って少し遊んでみる。 SBCL: sbcl-1.0.28-x86-linux-binary.tar.bz2 まずは、指定されたメモリの内容を出力する関数を定義。 ※ もともとは、文字列を出力する関数のつもりだったが…

リモートからコマンドを実行するHTTPサーバ

今日作成したデーモンサーバ作成モジュールを使って、HTTP通信を通して送信されたコマンドを実行するデーモンサーバを実装する。 この記事のものとは少し異なるが、そもそもデーモン用のモジュールを作成したのは、コマンド実行サーバを作りたかったから。 …

デーモン

以前に書いた『HTTPリクエストの中身を表示するだけのHTTPサーバ』を拡張して、デーモンサーバを作成する機会があったので、それをまとめてpackage化した。 プロセス(サーバ)をデーモン化すること自体は、以下のような処理で出来た。 (require :sb-posix) (d…

C++とcommon lispの実行速度比較(素数判定)

今日たまたま見つけた『(Sather を試そう) 1. Sather vs C++: 実行速度の比較』*1というページに触発され、lisp(sbcl-1.0.28)でも同様の比較を行ってみた。 C++のソースコードは、上記ページのものと同様だが、g++のオプションには'-O3'を渡している。 実行…

コンパイラノート表示

最近のバージョンのSBCL*1では、処理速度を最優先にする宣言を行って関数をコンパイルした場合でも、デフォルトではコンパイラノート*2が表示されないことがある*3。 そのため、最適化を確実に行いたい場合は、コンパイラノートを出力するように明示的に宣言…

一意なID(ポインタアドレス)取得

たまに、(正確な用語ではないが)オブジェクトごとに一意なIDを取得したいことがある。 Cで云うポインタがあれば、それが適切なのだが、common lispにはポインタを取得する方法は定義されていない(と思う)。 ただ、SBCLに限れば、ポインタ(アドレス)を取得す…

SBCLでマシンコードを直接実行

どこかで、sbclでメモリ領域に直接マシンコードを書き込んで実行できる、というような話を読んだような気がするので試してみた*1。 まずは、(マシンコードを取得するために)実行したい関数をCで定義する。 簡単なものがいいので、二つの変数を足すだけの関数…

HTTPリクエストの中身を表示するだけのHTTPサーバ

タイトルの通りのHTTPサーバを作成。 というか、ほとんど何も行っていないので、HTTPサーバとは云えないような気もする...。 ソースコード (require :sb-bsd-sockets) (use-package :sb-bsd-sockets) ;; 定数 (defconstant CRLF (coerce '(#\Return #\Newlin…

HTMLパーサ - ボトルネック解消

昨日のブログにあるHTMLパーサを試していたら、(組み込みのものではない)read-xxx系関数がボトルネックとなっていることが分かったので、修正する。一番、大きな影響を与えていたのは、この関数(若干簡略化)。 ;; (funcall fn c)がtになるまで、文字列を読み…

バイト列->文字列(コンディション処理)

バイト列を文字列に変換したい時には、sbclではsb-ext:octets-to-stringという関数を使えば良いのだが、これはそのままでは、文字コードの解釈に部分的にでも失敗するとバイト列全体の変換が失敗するという難があった*1。 バイト列のデコードに失敗した場合…

型分岐最適化

sbcl(1.0.28)は、適切に型宣言を行っておけば、冗長な型判定を実行コードから除外してくれるようだ。例えば次のようなマクロを定義する。 (defmacro get-type (obj) `(typecase ,obj (list :list) (fixnum :fixnum) (vector :vector) (t :others))) ; ↓のよ…

HTTPクライアント作成

簡単なcommon lispのHTTPクライアントをHTTPの勉強を兼ねて作成。ソースコード(*.lisp)は、約170行程度。まだまだ十分な完成度とは云えないが、せっかくなので公開してみる。 これ、tiny-http(0.1.3)。※置き場は暫定 インストールが必要な依存packageは次の…

文字列の正規化

昨日はMeCabバインディングを取り上げたが、MeCabを使うようなコードを書いている場合、文字列を正規化したくなることがたまにある。なので、簡単な文字列正規化関数をlispで実装してみることにする。 ※ ただし、文字の内部的なコード(char-code)に依存して…

MeCabバインディングとFFI

common lispからmecabを使う方法のメモ(sbcl依存)。まずは、多分一番直截的な方法: ;;;;;;;; ;;;; FFI(Foreign Function Interface)用のpackageを使用する (use-package :sb-alien) ;;;;;;;; ;;;; so読み込みと関数定義 (load-shared-object "/usr/local/lib…

配列用のクイックソート(簡単版)

昨日に引き続き、今日はクイックソートを書いてみる。一口にクイックソートと云っても、一番内部のループ(配列を二つに分割する処理)の実装方法にいろいろ変種があるので、とりあえず一番楽に実装できそうなものを思い出しつつ書いてみる。 (defun qsort (as …