tarでまとめるのとそのままではどっちが効率がいい?

タイトルそのままの実験です.

きっかけはBMSの読み込みが長いこと, しかし, CS版の弐寺ではかなり高速. この違いは何なのか考えた時, BMSはファイルがバラバラだからではないかと考察したのでそれを検証する次第です.

大体全体で60MBぐらいあるBMS曲(厭世アリス - LeaF)をディレクトリにそのまま展開したものとtarアーカイブしたもので用意しpython3で処理してみた.

コード

標準ライブラリで読み出し, ファイルとしてダンプする.

ディレクトリ版 (naive.py)
import os
import time

out = open("naive.dump", "wb")
start = time.time()

base = "[clover]LeaF_AliceinMisanthrope"
for e in os.listdir(base):
    buf = open(base + "/" + e, 'rb')
    out.write(buf.read())
    buf.close()

span = time.time() - start
print(span)
tar版 (tar.py)
import tarfile
import time

out = open("tar.dump", "wb")
start = time.time()

handle = tarfile.TarFile.open("ensei_tar.tar")

for e in handle.getmembers():
    if (e.isfile()):
        buf = handle.extractfile(e)
        out.write(buf.read())
        buf.close()

span = time.time() - start
print(span)

結果

単位はいずれも秒

% python3 naive.py 
0.22434473037719727
% python3 tar.py
0.4075179100036621

tarのほうが遅い
しかしこれぐらいの差だとあんまり実感がわかないぐらいの差しかない. 読み込み速度の違いには, どうやらこれ以外の要因も関わっているようだ. (デコードとか)

主観だが, ファイル読み込みはオーバーヘッドがそれなりにあると考えていて, 個別ファイルと1ファイルにまとまっているのでは後者のほうが速度的に有利だと考えていた. しかしこれはその予想を裏切ることになっている.

不思議なこと

かなり計測にばらつきが出る. コードを書いて一番初めに実行した時にはかなり時間がかかる(10秒ぐらい). 2回め以降は上記の結果になる. なぜだかわからない.

以上

関数の呼び出しについて

これは公開用ではありませんので、ググってきた方は戻ることをおすすめします。

 

関数の呼び出しについて


何気なく使っている関数ですが、どうして関数は処理を終えた後、無事呼び出し元に戻れるのでしょうか?

関数の呼び出しとはいわば、呼び出した地点から、関数の本体へジャンプして、処理をして、元の場所に戻ることです。

 

これを説明するには、関数がコンピューターの中で実際にどのように呼ばれているのかを考える必要があります。

難しい説明は抜きにします。

 

プログラムというのはコンピューターのメモリ上に展開されます。メモリには番地というのがあって、それを用いて、メモリ上の任意のデータにアクセスすることができます。

コンピューターはプログラムを実行する際に、メモリ上の十分な場所に、プログラムを一続きになるように展開します。

 

そのあとに、コンピューターはプログラムカウンタという現在実行している番地を記録する場所に、実行したいプログラムの一番最初の番地を登録します。

 

後は簡単です。コンピューターはプログラムカウンタの示す番地のデータを取ってきて処理をします。処理が終わったら、プログラムカウンタの指す番地を一つ先に進めます。つまり、今実行している番地の次の番地を指すようにします。

 

このロジックを繰り返すことで、コンピューターはプログラムを順々に実行していきます。

プログラムの終了を示すデータの入った番地のデータを読み出した地点で、コンピュータはプログラムの実行を終了させます。

 

ところで、コンピューターにはプログラムカウンタのほかに、様々な記憶領域があります。その一つに、積みゲーのごとく、番地を積んでおいておくスタックという場所があります。つまり、最近積んだ番地が一番上にあって、それをとってどうこうすることができます。どうこうした番地はスタックから取り除かれて、その一個下に積んであった番地が、一番上にきます。

 

関数はこのスタックを利用しています。

プログラムカウンタの指す番地のメモリに関数の呼び出しをする命令が書かれていたとします。

コンピュータはこのときプログラムカウンタの内容を(つまり指し示している番地を)スタックに積みます。あとは関数の始まりのデータのある番地を指すようにプログラムカウンタを書き換えます。そうすればコンピュータはその関数を実行することができます。

 

コンピュータはreturn命令のある番地を読み込んだときに関数を終了します。PHPにおいてはreturnのない関数でも、関数の最後にreturnが自動的に書かれます。

 

return命令を読み込んだとき、コンピュータはスタックから番地を取り出します。取り出した番地の一つとなりの番地をプログラムカウンタに書き込みます。これはどういうことかというと、呼び出し命令の書かれていた番地の隣の番地を実行するようにしたと言うことです。

 

こうして無事に関数から帰ってこれたわけです。

 

つづく

Works : MarkdownViewerQt - Markdownビューワー(Linux + Qt)

qlmarkdownみたいな手軽さでMarkdownを見られたら良いなと思ってqtで作成したものです.
今回は紹介だけで, ビルド可能なパッケージはまだ準備出来ていません.

追記:準備ができました.

続きを読む

LuaSDL2: ビルドできない件

LuaSDL2とはLuaでSDL2を利用するためのライブラリであるが, gitからcloneしてビルドしようとするとうまく行かない.

問題

/home/hoge/tmp/luasdl2/src/window.c: In function ‘hitTestCallback’:
/home/hoge/tmp/luasdl2/src/window.c:915:2: warning: implicit declaration of function ‘lua_geti’ [-Wimplicit-function-declaration]
  lua_geti(cd->L, LUA_REGISTRYINDEX, cd->ref);
  ^
/home/hoge/tmp/luasdl2/src/window.c: In function ‘l_window_setHitTest’:
/home/hoge/tmp/luasdl2/src/window.c:950:10: error: void value not ignored as it ought to be
  if ((ut = lua_getuservalue(L, 1)) == LUA_TUSERDATA) {
          ^
/home/hoge/tmp/luasdl2/src/window.c:947:6: warning: variable ‘ut’ set but not used [-Wunused-but-set-variable]
  int ut;
      ^
CMakeFiles/SDL.dir/build.make:590: ターゲット 'CMakeFiles/SDL.dir/src/window.c.o' のレシピで失敗しました
make[2]: *** [CMakeFiles/SDL.dir/src/window.c.o] エラー 1
CMakeFiles/Makefile2:67: ターゲット 'CMakeFiles/SDL.dir/all' のレシピで失敗しました

warningは良いとして, errorについてみてみる.
lua_getuservalue関数はvoidらしい.
こんな単純なミスを犯すだろうか?
Lua5.2のリファレンスを見てみてもこの関数はvoidを返す.
ではLua5.3では?
intを返すのだ.

解決策

  • liblua-5.3-dev (Ubuntuの場合)をインストール
  • cmake .. -DWITH_LUAVER=53 でcmakeする

これで出来ました.
ちなみにgithubのissueに上がっています. 調べが甘かったです. apiリファレンスやヘッダファイルを調べるはめになりました.

cmakeのデフォルトがLua5.2らしいけど, デフォルトでビルドすると失敗するのは解決した今なら笑える冗談です. (バグだというのは重々承知の上で)

以上.

C# : NAudio と 高速フーリエ変換(FFT)

NAudioについての日本語の記事が少ないので備忘録も兼ねてNAudioでのFFTのやり方を書きます.

今回の目標はマイクから取得した音をフーリエ変換することです.

いかんせん自分が信号について素人なので、記事の対象読者は次の通りです。

  • 理屈に詳しくないが、フーリエ変換を活用したい。
  • NAudioの日本語での解説が見たい。

読者がゼロにならないことを願います。

続きを読む

プログラミング : リーダブルコードを読もう

単純に本の紹介です.

www.oreilly.co.jp

プログラミングをする者にとって一度は読んでおきたい本の一冊だと思います.
基本的なことしか書かれていない.しかし,それがいい.

プログラムをReadable(読めるように)書くにはどうしたらよいかをわかりやすく説明しています.
昨日の自分は他人.独りプログラマーでもぜひ読むべきだと思います.
上級者には面白みもないようですが...

言語がごっちゃの本なので,ちょっとほかの言語も読めないときついかもしれません(ただし,使われている文法はほぼ基本的なもの.C言語ができれば読破はたやすいでしょう)

以上 Raptor でした.