[beatoraja]「楽曲読み込み」「楽曲全更新」違いは?両方押すの?どっちが速い?ヒープサイズは?彼女は?年収は?学歴は?調べてみました。ついでに自前で用意したOpenJDKを使うバッチ2024最新版も [BMS]
背景
beatorajaを使用し始めて、[楽曲読み込み]と[楽曲全更新]の違いがよく分からなかった。どっちを押してもかなり時間がかかるなと思った。
そこで、本noteでは以下4点について調べ解説していこうと思う。
[楽曲読み込み][楽曲全更新]の処理内容の違い
[楽曲読み込み][楽曲全更新]のどちらかだけで良いのか
[楽曲読み込み][楽曲全更新]をするにあたり、まずい設定(ヒープの割り当て-Xms4g -Xmx4gのとこ)は存在するのか
[楽曲読み込み][楽曲全更新]の処理時間の違い
結論では、簡潔にどうするのが正解かだけを述べ、詳しい解説はしない。
はじめに(言い訳)
この記事は、beatorajaのソースコードを本件に関係ありそうなところの流し読みを行った上で書いています。しかし、筆者はプログラマーではないです。よって理解度が怪しかったり、複雑そうな処理は深追いしてなかったり、手元に開発環境すら用意せず以下のリポジトリのソースコードをWebブラウザから眺めているだけだったり(言ったの2回目か?)と微妙な部分が山積です。ですが、実験結果と絡めて[楽曲読み込み][楽曲全更新]どっち押したほうが良いかは考察できたと思います。
結論
現状(0.8.8)[楽曲全更新]だけ押していれば良いと思います。
[楽曲全更新]の方が速い上にタグやFAVORITEは保持してくれます。
後から追加されたpreview音源も[楽曲全更新]じゃないと読み込めないらしいです。ただ、preview音源については修正するプルリクが来ているっぽいので次のバージョンでは修正されるかもしれません。
もし[楽曲読み込み]の方が速いという人がいれば、そちらだけを押していれば良いと思います。
[楽曲読み込み]⇒[楽曲全更新]のように2回押すのは無意味だと思われます。
DBが壊れた場合、songdata.dbやsonginfo.dbを消して再生成するのが一番速いと思いますが、タグやFAVORITEは消えてしまいます。スコアは別のDBファイルなので関係ないです。
ヒープの割り当ては-Xmx4g未満にはしない方が良いと思います。
例えば、-Xms2g -Xmx2gだと新規にsongdata.dbを作る際や[楽曲全更新]時にOutOfMemoryという致命的なエラーが私の環境だと100%再現すると思われ、楽曲情報の構築が完了できませんでした。
-Xms4g -Xmx4g以上が無難だと思います。
JRE同梱版のexeは-Xms1024m -Xmx4096mなので問題ないです。
同梱されていないOpenJDKを試したい場合は、後述の私の使っているバッチの内容をそのまま流用していただければよいと思います。
[楽曲読み込み][楽曲全更新]の処理内容の違い
画面にはこのようにボタンがありますが実際の意味は以下です。
UPDATE_DATABASE = [楽曲読み込み]= Update BMS database
REBUILD_DATABASE = [楽曲全更新] = Rebuild BMS Database
【参考】
https://github.com/exch-bms2/beatoraja/tree/master/src/resources
[楽曲読み込み][楽曲全更新]ボタンが押されたときの処理を追うと、
[loadDiffBMS][loadAllBMS]とある。
[楽曲読み込み](loadDiffBMS)は追加削除分のみを更新するとのことである。
[楽曲全更新](loadAllBMS)は全て更新することがうかがえる。
それで、何段階か飛ばしてしまったのですが、最終的にはここのupdateSongDatasメソッドに、コンフィグのBMS Pathで登録したパスがすべて渡されて、BMSファイルがあるディレクトリかを調べて、songdata.dbやsonginfo.dbが構築されるということだと思います。多分…
この時に、[全楽曲更新]した際は、songdata.dbのfolder, songテーブルを削除してから構築処理が始まります。削除前にタグとFAVは保持するようです。
いったんテーブルを削除したとしても、この後の処理で構築されるDBは同じになることが期待されるので、処理時間を考えなければどっちを押しても構わないと思います。
テーブルを削除しない[楽曲読み込み]の場合には、既存のBMSに関する処理は飛ばすようなことをしていると思うのですが、詳しい処理は私には難しく追えていません。ただ、後述していきますが[全楽曲更新]の方が速く終わります…
[楽曲読み込み][楽曲全更新]のどちらかだけで良いのか
上述した通り、どちらか一方を押せば、songdata.dbとsonginfo.dbが構築されるので両方押す意味はないです。
結論に至った実験の前提
JVM設定
私はMochaでJRE同梱版(beatoraja-0.8.8-jre-win64)をDLし使っていました。しかしある日、同梱版以外のOpenJDKを試してみたくなりました。パフォーマンスが向上するとかの期待はしていませんでしたが、とりあえずやることにしました。
OpenJDKの選定や起動オプションについては以下が参考になりました。
私が使ってる起動バッチ (2024)
beatoraja-config.bat
REM *** Set system-wide "_JAVA_OPTIONS" environment variable to use OpenGL pipeline (improved performance of > 30% potentially. Also use anti-aliasing for non-LR2 fonts, and finally allow Swing framework to utilize AA and GTKLookAndFeel for config window. ***
set _JAVA_OPTIONS='-Dsun.java2d.opengl=true -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'
set OPENJDK_PATH=D:\beatoraja\jdk23.0.1_8\bin\java.exe
set OPENJFX_PATH=D:\beatoraja\javafx-sdk-23.0.1\lib
set ADD_MODULES=javafx.controls,javafx.fxml
set CLASSPATH=beatoraja.jar;ir/*
set JVM_OPTIONS=-XX:+UseShenandoahGC -XX:+ExplicitGCInvokesConcurrent -XX:+TieredCompilation -XX:+UseNUMA -XX:+AlwaysPreTouch -XX:+UsePerfData -XX:+UseThreadPriorities -XX:+ShowCodeDetailsInExceptionMessages
pushd %~dp0
start /abovenormal /affinity 55 /wait /b %OPENJDK_PATH% -Xms4g -Xmx4g --module-path %OPENJFX_PATH% --add-modules %ADD_MODULES% %JVM_OPTIONS% bms.player.beatoraja.MainLoader
popd
pause
上から自分で書き足した設定を説明すると
set OPENJDK_PATH=D:\beatoraja\jdk23.0.1_8\bin\java.exe
https://corretto.aws/downloads/latest/amazon-corretto-23-x64-windows-jdk.zip
↑Amazon開発のOpenJDKです、直リンなっとるかな?Java 23
set OPENJFX_PATH=D:\beatoraja\javafx-sdk-23.0.1\lib
set ADD_MODULES=javafx.controls,javafx.fxml
いつしかOpenJDKから分離して別で用意しなければならなくなりました。ついでにADD_MODULESを書く必要があります。最低限のモジュールを読むようになっています。読み込めるものは全部読み込むみたいな荒業でも動きはします。下のサイトで、Java 23に合うものx64をDLして配置。
beatorajaに同梱されているLiberica JDKはJavaFXが内蔵されたパッケージでbeatorajaからすれば、JavaFXが普通に使えるし、toraja、libericaはコーヒー繋がりだしで最適の同梱JREかもしれませんね。(そうなってくるとわざわざAmazonのJDKを試している意味とは?)
CLASSPATH=beatoraja.jar;ir/*
「ir/*」以下を見て「minir-530.jar」をクラスパスに追加してMinIRに参加する設定。
JVMオプションたちの解説(弱)
鵜呑みにした設定たち。わかる範囲で補足していく。たぶん私が参考にした人の方が詳しいのでそれを信じます。リファレンスマニュアルか何か見たかったけどよく分からない。こんなJVMオプション存在しているのか?
set JVM_OPTIONS=
-XX:+UseShenandoahGC
従来の「G1」よりも優れたガベージコレクタ「ShenandoahGC」を使う設定
-XX:+ExplicitGCInvokesConcurrent
よく分からないがFullGCの影響の低減が期待される(FullGCは時間かかるから起こってほしくない)
-XX:+TieredCompilation
階層型コンパイルを有効にする。何か良いのだろうか?
-XX:+UseNUMA
よく分からないヒープ管理のなにか
-XX:+AlwaysPreTouch
まず最初にヒープが使うページをメモリに確保してしまう
-XX:+UsePerfData
オフにした方がパフォーマンス的によさそうだが、今回は明示的に+にした。ヒープを観察するためである。これを-にすると「jconsole.exe」が使えなくなる。今回はjconsoleでヒープが枯渇しないかも見ておく方針。「D:\beatoraja\jdk23.0.1_8\bin\jconsole.exe」みたいな感じでJDKには付属してくるはず。
-XX:+UseThreadPriorities
効果のほどは疑わしいが、startコマンドの/abovenormalで優先度を上げているのでこれも使う。
-XX:+ShowCodeDetailsInExceptionMessages
改善されたNullPointerExceptionメッセージの出力を有効にします。Java開発者じゃないんで要らん機能かもな。一応ログに出てきたらなんかわかるかも?
べた書きのやつ
-Xms4g -Xmx4g
言わずと知れたヒープメモリの設定。私の環境、というが多くの人の環境では4gは使い切ってしまうと推測しているので、下限の方も-Xms4gとしています。
「start /abovenormal /affinity 55 /wait /b」解説
start
指定したアプリやコマンド、今回はbeatorajaを起動する
/abovenormal
beatorajaの優先度を上げる設定
/affinity 55
beatorajaが動くスレッドを物理コアのみにする。
16進数の「55」というのは2進数で「01010101」使わないコアを1でマスクするという話なのでこうしている。
私の使っているBMS用PCは4物理4論理の8コアのはずなのでこのような設定にしてみた。正直プラシーボの気もするし、最近のCPUだと全く意味がないと思われるので、こだわりがないなら消したほうが良いオプションです。
/wait /b
このコマンドプロンプトのウィンドウでbeatorajaを起動し、beatorajaが終了するまでウィンドウを閉じない。ゆえに直近のエラーとかが見れる。/bがない場合は別ウィンドウで起動する。
改めて実験の前提まとめ
PCスペック
CPU: (2012) Intel Xeon CPU E3-1270 V2 @ 3.50GHz
RAM: 20.0 GB
OS: Windows 10 Pro
GPU: (2016) GeForce GTX 1070 8GB
SSD: SAMSUNG SSD MZ-QLW1T90 PM963 1.92TB PCI-Express Gen 3.0 x4
(BMSデータは全部これに入れてる)
JVM
上述の「beatoraja-config.bat」で起動される通り。
Amazon Corretto 23.0.1_8
JavaFX SDK 23.0.1
所持譜面数
ここは「楽曲読み込み」「楽曲全更新」にかなりの負荷を与える要素だと思うのでしっかり確認しておきます。
BeMusicSeekerで確認したところ、重複はほとんどなく以下の通りでした。
181473曲 24473フォルダ
beatorajaのsongdata.dbではbmsonも読み込むためか、181713となっていました。
LR2では問題がないディレクトリ構造でも、beatorajaでは読み込めないという可能性はありますが、ほとんどのbms, bme, bml, pms, bmsonは読み込み可能な状態と思われます。
[楽曲読み込み][楽曲全更新]をするにあたり、まずい設定(ヒープの割り当て-Xms4g -Xmx4gのとこ)は存在するのか
以下のように、-Xms2g -Xmx2g G1GCの環境で、楽曲DBがない状態で、新規に[楽曲読み込み]した際にOutOfMemoryが発生しました。
-Xms2g -Xmx2g ShenandoahGCの環境でも同様にOOMが発生しました。
以上のように、私の環境では-Xms2g -Xmx2gだと必ずOOMが発生してしまいます。
よって、-Xms2g -Xmx2gといったヒープの割り当てを絞るような設定は行わない方が良いと思います。
そもそもbeatorajaの注意書きにヒープをたくさん使いますと書いてあるので4gはマストと考えた方が良いと思います。
[楽曲読み込み][楽曲全更新]の処理時間の違い
プロンプトに以下のようなログが出るのでスプシにまとめました。実際に出てくるのは「情報:」の行で「4GB~」とか書いてあるのは実行状況のメモです。
4GB [楽曲全更新] (REBUILD)
情報: 楽曲更新完了 : Time - 1964661 1曲あたりの時間 - 10
8GB [楽曲全更新] (REBUILD)
情報: 楽曲更新完了 : Time - 2017882 1曲あたりの時間 - 11
8GB [楽曲全更新] (REBUILD)
情報: 楽曲更新完了 : Time - 1841977 1曲あたりの時間 - 10
4GB [楽曲全更新] (REBUILD)
情報: 楽曲更新完了 : Time - 1912555 1曲あたりの時間 - 10
8GB [楽曲読み込み] (UPDATE) 新規構築後全く差分がない状態
情報: 楽曲更新完了 : Time - 3039220 1曲あたりの時間 - 379902
4GB [楽曲読み込み] (UPDATE) REBUILD後全く差分がない状態
情報: 楽曲更新完了 : Time - 3348816 1曲あたりの時間 - 418602
4GB [楽曲読み込み] (UPDATE) 少し差分がある
情報: 楽曲更新完了 : Time - 3172066 1曲あたりの時間 - 37318
8GB [楽曲全更新] (DB削除新規)
情報: 楽曲更新完了 : Time - 1568545 1曲あたりの時間 - 8
8GB [楽曲全更新] (DB削除新規)
情報: 楽曲更新完了 : Time - 1629833 1曲あたりの時間 - 8
4GB [楽曲全更新] (DB削除新規)
情報: 楽曲更新完了 : Time - 1612351 1曲あたりの時間 - 8
ヒープサイズは時間に影響がなさそうですが、
私の環境だと明らかに[楽曲読み込み]が遅いです。50分もかかります。
なんか変なBMSでも紛れているのでしょうか?感覚的には、DBに情報が既存のBMSが多い方が処理が速くなりそうなのですが…
原因不明ですが[楽曲全更新](REBUILD)なら30分程度で終わります。
いかがでしたか?
今回は背景で述べた4点について調べきることができました。
こまかい内部の処理については難しいのでわかりませんでした。
運用上はどうすれば良いかということは判明したので良かったと思います。
まあ、おま環の可能性もあるのですが…
おまけ
ヒープ4GBでの様子