2019年の振り返りと2020年の目標
やってきたことを忘れないためにも2019年を振り返ってみて、2020年の目標を立てたいと思います。
やってきたことですが、個人的な取り組みとしていろいろな言語でパーサーの実装をしてきました。最初に実装をしたJavaでの方針をもとにほかの言語でも作ってみたのですが、特にジェネリクスが使えないgoではJavaの実装をそのまま持っていくことが出来なかったので苦労した覚えがあります。
それから、ScalaについてはJsonをパースした後に任意の型に変換する部分がまだ作っている最中なので、こちらも時間があるときに進めていきたいです。
GitHub - teruuuuuu/parsers
scalaでjsonをパース後のASTを扱いやすいように型変換する方法について調べてみた - teruuuのブログ
あと勉強を続けていたドメイン駆動設計と関数型言語で用いられるモナドについても抵抗が前よりもない気がしています。
ecサイトをモデリングしてscalaで実装してみる - teruuuのブログ
Scalaで作って理解するモナド - teruuuのブログ
関数型言語による簡潔な表現はドメイン駆動設計と相性がよさそうだと思いますし、"Functional and Reactive Domain Modeling "という本も出ているようなので2020年はドメイン駆動設計の中で関数型言語をうまく使う方法についても勉強していきたいところであります。
Manning | Functional and Reactive Domain Modeling
また、知識の幅を広げるためにPythonでの株取引シミュレーションやISUCOnの過去問を解いたり、verilogでCPUのシミュレーションをしたりと興味があったものは学ぶようにしていました。
株とPythonの本を読んで株取引のシミュレーションを実装してみた - teruuuのブログ
ISUCON9 Finalのベンチマークを動かして遊んでみた - teruuuのブログ
CPUの創り方をもとにverilog-hdlでシミュレーションをしてみた - teruuuのブログ
RSA暗号の仕組みを追ってみた - teruuuのブログ
2020年の目標について、自分自身の得意分野というものが特になく一つのことを集中して続けるということがあまりなかったので、自分の得意分野を持てるようになりたいと思います。 具体的には、パーサーの実装にも慣れてきた気がするのでそろそろ自作言語についても学んでいきたいです。それから去年は転職をした年でもあるので、業務にいかせる何かについても取り組んでいく予定です。
JNIを使ってJavaからCとRustを呼び出してみた
JNIとは
JNIとはJavaからネイティブコードを呼び出すための機能です。例えばC言語であればgccでコンパイルするときにsharedのオプションを有効にすることで共有ライブラリが作れるので、Java側ではSystem.loadLibraryやSystem.loadで共有ライブラリを読み込むと呼び出せるようになれます。
計算量の多い部分をネイティブコードに置き換えることで高速化を狙えるらしいのですが、メモリ管理や排他制御などに気を付けないと不具合や低速化を招くので使うポイントはちゃんと考える必要があるようです。
今回はC言語とRustをコンパイルして共有ライブラリを出力してJavaから呼び出して、実行時間の比較を行いたいと思います。
続きを読むISUCON9 Finalのベンチマークを動かして遊んでみた
ISUCONとは
ISUCONとはWebアプリケーションの高速化を競うコンテストです。2011年から毎回開催されていまして、現在(2019年時点)で9回コンテストが開催されています。詳しい説明は公式ページがあるので、そちらを見ればよいかと思います。コンテストで動かすソースはgithubで公開されています。 https://github.com/isucon コンテストで扱う言語はgo, ruby, python, php, perlと良くWeb系で扱われる言語は含まれているようです。
ISUCON9 Finalの環境構築
ISUCON9の本選で扱われたソースは以下になります。 https://github.com/isucon/isucon9-final
環境はdockerで構築するようですが、ビルドにMakefileを使っており、また以下のベンチマークビルド用のMakefileを見るとMac, Linux向けでビルドを実行しているのが確認できます。 https://github.com/isucon/isucon9-final/blob/master/bench/Makefile
自分はWindowsの環境で確認しようと思ったのですが、そのままではうまく動かなそうだったのでHyper-v上のubuntuで環境を構築することにしました。
続きを読む複数行grepする方法を調べてみた
複数行まとめてgrepしたいことがあったので、調べてみたら以下で説明で同じことをやろうとしていました。
grepに対して -P
のオプションでPerlの正規表現を使えるようにし、 -z
のオプションでテキスト全体を一つの行として扱うことで複数行のgrepが実現できるようです。
windows10のwslで試しに実行してみたところ。
$ cat test.txt xaaaxxxxxxxxx xbbbxxxxxxxxx xcccxxxxxxxxx xaaaxxxxxxxxx xbbbxxxxxxxxx xaaaxxxxxxxxx xcccxxxxxxxxx xaaaxxxxxxxxx xbbbxxxxxxxxx xcccxxxxxxxxx $ grep -Pzon ".*aaa.*\n.*bbb.*\n.*aaa.*\n" test.txt 1:xaaaxxxxxxxxx xbbbxxxxxxxxx xaaaxxxxxxxxx
と .*aaa.*\n.*bbb.*\n.*aaa.*\n
の3行を対象にgrepできていることが確認できました。ただし、これだと -z
でテキスト全体が1行という扱いになるため -n
で行を表示しようとしてもうまくいかないようです。
Scalaで作って理解するモナド
Haskellでのモナド型クラスが有名で、Haskellの創始者のひとりであるフィリップ・ワドラーはモナドについて"自己関手の圏におけるモノイド対象"と答えているらしい。そのほかにも調べているとモナドは箱に入った値を返す関数を箱の中の値に適用するといったものもあり、大体が数学の専門的な内容であったり抽象的な表現だったりするの勉強を始めたばかりの人には分かりづらい印象です。ScalaではOptionやFutureがよく使われるモナドだと思います。自分がScalaを勉強し始めたころはOptionについてはそんなに抵抗がありませんでしたが、Webアプリを作るときとかに出てくるFutureはfor式などで出てきてややこしかった気がします。
今回は自分でモナドのインスタンスを実装してみてfor式に対する抵抗がなくなることを目指したいと思います。
続きを読むscalaでjsonをパース後のASTを扱いやすいように型変換する方法について調べてみた
以前の作業でscalaでJSONをパースできるようになりましたが、そのままの抽象構文木(AST)の状態だと扱いづらいので変換する方法について調べてみます。
調べたところspray-json-shapelessというものがあり、これが丁度やりたいことに近いかと思います。
spray-json-shapelessでは以下のようにパース後の結果に対してconvertTo[T]を呼び出すことで任意のオブジェクトに変換できているようです。
package example object TrySprayShapeless extends App { import spray.json._ import fommil.sjs.FamilyFormats._ case class Foo(a: String, b: Double, c: Boolean) val sprayJsonConvertResult = """{"a":"foo","b":42.0,"c":true}""".parseJson.convertTo[Foo] println(sprayJsonConvertResult) }
spray-json-shapelessはshapelessというscalaでジェネリックプログラミングを可能にするライブラリを使用しているのでここまでできると思うのですが、まずはspray-json自身で基本的な型に変換するまでの処理を追えるようになりたいと思います。
続きを読む