Blog

StarField 一周目クリア

Bethesdaゲームを順当に宇宙に移したな〜という感想。 いつも通りシステムに対する説明がたりてなかったりするけど十分面白い。

gradle が遅いなと思ったら gradle-profiler を使おう

https://github.com/gradle/gradle-profiler

gradle の処理がなんだか遅いなってときがある。

サッとググッて出てくる情報だと、--profile つけろとか、--scan 使えとか書いてある。 --profile は情報がざっくりしすぎていてよくわからないし、--scan は gradle.org に情報がアップロードされちゃうのがちょっと。。 --profile って結局は、「どのタスクが遅いか」はわかるんだけど、どのプラグインが遅いか、とかはよくわからなかったりするんだよね。

gradle-profiler を使うと、どのプラグインが時間食ってるか、みたいなことをサッとしれて便利。 何回か動かしたベンチマークの結果をレポートにまとめてくれるので、gradle の速度チューニングした結果の評価にも便利。

benchmark の取り方

$ gradle-profiler --benchmark --project-dir . assemble

とかやって動かす。

数回試行された結果が以下のような HTML で生成される。

profiling の仕方

jfr や async-profiler をかけながらgradleを動かせるのも便利すぎる。

なんだか最近gradle遅いな、と思ったらgradle-profilerかけると良いと思う。

gradle-profiler --profile async-profiler --project-dir . assemble

async-profiler 以外にも jfr や YouProfiler などを使うことも可能。

以下のような見慣れた flamegraph を得ることができる。

これをやった結果、spring の dependencyManagement に個別の dependency をいっぱい指定すると遅いから platform project 作ったほうが良さそうだなぁ、とかそういうことがわかったりする。

let's plot kotlin で X 軸を YearMonth にしたときにソートされないよって場合

https://github.com/JetBrains/lets-plot-kotlin/issues/48

epoch millis にして scaleXDateTime するのが良さそう

JDK の JIT の様子を眺める方法 6選

JDK の JIT の様子を眺める方法について考える。

実際には 現代のサーバーサイドエンジニアリングでは JDK の JIT がパフォーマンスイシューの原因になっているケースは極めて少ない が、JIT がどんなふうなタイミングで発生しているかを把握しておくことは人生にとって有益だと思う。

ログを出すと若干のオーバーヘッドがあると思うけど、JIT のログは起動直後にちょっと出るだけで量も大したことないので気にしなくていいレベルな気がする。

JFR で見る

王道っぽい。

JFR Event Streaming を使って収集する

Java 14 以後で利用可能な JEP 349: JFR Event Streaming を使って micrometer などに出力する。この方法だと、JFR が動く前の JIT イベントが取れない気がする。 https://matsumana.info/blog/2020/09/20/jvm-jit-compilation-metrics/

Unified Logging に JIT log を出す

https://matsumana.info/blog/2020/09/22/jvm-jit-compilation-metrics-with-mtail/

-Xlog:jit+compilation=debug というオプションを指定することで、JIT のログを取れる。Unified JVM Logging 形式なので取り回しがわりとしやすいかも。

ref. https://www.slideshare.net/slideshow/embed_code/key/BLJsjK56iDL0y

-XX:+PrintCompilation

-XX:+PrintCompilation をつけると、JIT コンパイルログが stdout に出力される。軽く見るにはいいかも。Unified Logging でとれる今となってはあえてこれを使う理由はないかも。

ref. https://www.slideshare.net/nttdata-tech/jit-compiler-jjugccc-2020-fall-nttdata-sakata?slide=42

-XX:+LogCompilation

-XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation つけるとファイルにログが出力される。ファイル名は current directory の hotspot_pid$$.log となる。XML で出力されるので処理しやすいかもしれない。

JitWatch で眺めると楽しい。

ref. https://yuya-hirooka.hatenablog.com/entry/2021/04/30/234227

https://github.com/AdoptOpenJDK/jitwatch/releases/tag/1.4.7 このへんからダウンロードできるので使うとよい。

wget https://github.com/AdoptOpenJDK/jitwatch/releases/download/1.4.7/jitwatch-ui-1.4.7-shaded-mac-m1.jar
java -jar jitwatch-ui-1.4.7-shaded-mac-m1.jar

Remnant 2 クリア

Remnant 2 をクリア。難易度はサバイバー。サバイバーでも十分すぎるぐらいに難しい。特にボス。ラスボスとラビリンスがキツかった。。 ソウル系のTPSというやつ。

かなりゲームバランス良くて、楽しめた。雰囲気もダクソっぽくて楽しい。

自動生成ダンジョンなのは野心的だが、結局のところ、ソウル系ってボスが命ってことになっちゃうので、ボスまわりは毎回同じなので、刺激は薄れちゃうかもなぁ。

ゲーム内がかなり説明が不親切で、例えば特性が65が上限なのにそれがゲーム内だとさっぱりわからんとかそういうのはある。。 が、基本的には楽しめた。

攻略につまった場合は野良の協力者を召喚すればうまくいくこともあるので楽しい。

自作ブログの構成更新

k8s を趣味でも使うか、、と思ってこのブログでも DigitalOcean の k8s を使うようにしてみたのだが、DigitalOcean への月々の支払いが $100/mo とかになってきて、さすがにたけーなと。円安だし。。

というわけで、もう少し安くすることを考えてみた。

DigitalOcean Apps というのがあったので、これを使うようにしてみる。これは AWS App Runner みたいなやつで、簡単に docker image をホスティングできるし、TLS 終端とかもいい感じにやってくれる。

といった感じのオペレーションをしたらとりあえず完了。

これでとりあえず $40/mo ぐらいにはなった。本当は、admin サイトと web サイトを統合して一つの app に入れるようにしたらもう少しコストを圧縮可能だが、、アプリのコードをそこそこいじらないと行けないと思うので、一旦ここまで。

kravis をやめて letsPlot に移行した

どちらも ggplot2 を意識したインターフェース。

というか kravis は ggplot2 の wrapper なので、ggplot2 の実装をそのまま使えて便利っちゃ便利。 一方で、ggplot2 をインストールしなきゃいけないので面倒なこともある。docker で動かすこともできるのだが、動作にちょっとコツが必要。

kravis は krangl と同じ作者なので、相性がよくて便利だったのだが、kotlinx-dataframe 時代になったのでその優位性は失われた。

letsPlot kotlin は kotlin で実装されてるのでインストールが楽。 昔は letsPlot は機能が少なすぎたが、最近は letsPlot は機能がだいぶ増えてきたので letsPlot に移行することにする。

    implementation("org.jetbrains.lets-plot:lets-plot-common:3.2.0")
    implementation("org.jetbrains.lets-plot:lets-plot-image-export:3.2.0")
    implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.4.1")

とかやる。

    private fun renderSummary(df: DataFrame<Any?>) {
        val p = letsPlot(df.toMap()) +
            geomBar(alpha = 0.3) { x = "year"; fill = "severity" } +
            facetWrap(facets = arrayOf("product")) +
            themeLight()

        ggsave(p, "./reports/summary.png", path = ".")
    }

みたいに実装する。ggsave() とか ggplot2 感がすごい。

LocalDate をそのまま入れておくと描画できないとか微妙に癖はあるが。。 datalore との相性も jetbrains がメンテしているだけあって良い気がするので、今後はこっちをつかっていきたい所存。

Spring の @Scheduled は 1つのスレッドで動く。

https://qiita.com/ksh-fthr/items/34126324cc71bfc4d469 https://tech.excite.co.jp/entry/2022/12/09/101008

Spring の @Scheduled はデフォルトでは1つのスレッドで動くので、必要ならば spring.task.scheduling.pool.size を設定してプールサイズを大きくしておく必要があります。

queue にどのぐらい積まれているかは actuator を prometheus で出している場合、 executor_queued_tasks で確認できるので、これを監視すると良い。

fsmonitor のソケットが原因で generateGitProperties がエラーになる

	> java.io.IOException: Cannot snapshot .git/fsmonitor--daemon.ipc: not a regular file

というエラーが generateGitProperties タスクで発生する。

rm -rf .git/**/fsmonitor-* をした上で、git config --global fsmonitor.socketDir "$HOME/.git-fsmonitor" としたほうが良いと思われる。

これでダメなら git config --global core.fsmonitor false か。

SparkSQL で暗黙の型変換を抑制する

automatic type coercing が起きると期待しない結果になることがある。

select if('-999999999999' < 0, true, false) as s, if(-999999999999 < 0, true, false) as i

↑の結果が、s は false, i は true となる。 数字をうっかり文字列のまま使ってる場合、int の範囲を超えた場合に false になる。

こういう暗黙の型変換は困るケースも多いので、spark.sql.ansi.enabled を有効に設定することを検討する。

spark.conf.set("spark.sql.ansi.enabled", "true")

この環境下では、上記のクエリーは invalid input syntax for type numeric: -999999999999 と型変換エラーになる。

https://spark.apache.org/docs/3.4.1/sql-ref-ansi-compliance.html

大規模言語モデルは新たな知能か――ChatGPTが変えた世界 (岩波科学ライブラリー)

https://amzn.to/44CzDFh

数式なども登場せず、LLM について過度な期待をもたせすぎず、それでいて未来への展望を冷静に語っている良書だと思います。 ChatGPT について学びたい人、特に文系の人にはオススメ。

OkHttp3 では GET request に content-body が送れない

https://github.com/square/okhttp/issues/3154

elasticsearch/opensearch 等では GET request に content-body をつける必要があるが、OkHttp3 では対応していない。強い気持ちがあるようだ。

diablo4 のストーリーをやった

ネクロマンサーでレベル50まで。 tier1でやった。

楽しかった。エクスプロージョンが使いこなせると楽しくなったかなー。

Java の ByteBuffer の endian は big endian がデフォルト

一般的なプログラミング言語に慣れていると「普通に考えたらデフォルトは machine native だろ」って考えがちだけど、Java の Byte buffer は big endian がデフォルトなので気をつけよう!! めっちゃ時間溶けた。

https://docs.oracle.com/javase/jp/6/api/java/nio/ByteBuffer.html

Exposed を試した

普段は mybatis を使うことが多いのだが、Prototyping する機会があり、たまには Exposed など使ってみることにした。 Exposed は JetBrains 製なので kotlin と相性良さそうかなーと。

で、実際使ってみると以下のような困ったことがあった。

というわけで、今日もまた mybatis へと戻っていくのだった。

(実は Exposed でもやりようがあるのかもしれないが見つけられなかった)

自分の Blog admin site を書き直した

Kweb がどうも日本語入力がうまくいかなくなったので諦めて普通の Ktor ウェブアプリに戻した。 機能的にはほぼ同じだがシンプルになった。Kweb で少しシンプルに書けるかなーと思ったのだが、そうでもなかったし、、

相変わらず微妙に速度が遅いのだが、、この遅さはなぜか DigitalOcean を使っている結果、シンガポールにデータベースサーバーがあるので、、というよくわからない理由によるものなので、RDSにでも移すかなぁ。

magic research をクリアした

https://mcolotto.github.io/magic-research-demo/website/

Android 版をシコシコとやってた。いわゆる放置ゲー的なやつだけど、この手のやつでは一番おもしろかった。 トータルで 49日かかりました。

何が面白いかと言うとですね。。ゲームバランスが絶妙で、ボスが絶妙に倒せないのと、戦術を工夫しないと先に進めないようになっててめっちゃ楽しい。 転生するたびに見える景色が変わっていく感じがたまらないですな。

blog を更新しようとしたら、落ちた。

なんか知らんけど、 blog を更新しようとしたら落ちた。 kweb が kotlin-logging の 4 beta に依存してて、 class not found な状態に。悲しい。

しょうがないからアプリ自体も kotlin-loggin 4 beta に依存するようにして解決。

ついでに kweb 自体のバージョンも上げたのだが、普通の input box が、すげー微妙な挙動になってつらい。。日本語の入力時に入力途中の文字が入っちゃうというよくあるやつ。 kweb 飽きたし、そのうち全面的に書き直したいかもしれない。

SPA にするのが良いと思うが、どうしようかなぁ。

Marvel's Spider-Man: Miles Morales

https://www.playstation.com/ja-jp/games/marvels-spider-man-miles-morales/

PS5でクリア。 正当な拡張コンテンツという感じ。Spider man 2 も発売決定してるのでそれも楽しみですね。

Watchdogs 1/2 クリア

Watchdogs LEGION をクリアしてから youtube のレビューなどを見たところ、以下のような意見が散見された。

Watchdogs LEGION も結構面白かったのに 1,2 のほうが良かったという意見が多いようなので、そんならやってみるかということでヤッてみた。

やってみるとじっさい、カーチェイス多い。カーチェイス多すぎるぐらい。あと 1 はドローンないからドンパチメインになりがち。 ストーリーもまぁ 1 とか 2 は濃い。2の世界観はなんというか、学生の正義の味方気取りのテロリストって感じでノリについていけない感じはありつつ。。

全体としては 1 も 2 も面白かった。LEGION は方向性としては面白い気がするので、AI の進化を取り入れていければ今後この方向性はもっとおもしろくなるんじゃないかなーと期待している。LEGION の良くないのは、キャラクターを収監されちゃうところな気はするのと、キャラクターごとの個性が弱いってところだと思う。RimWorld とかのほうがよほど思い入れが持ちやすいね。