diary

I like Hatena Star with a text selection.

2024-04-04

github.com

Steep で不要な RBS::Location#to_s の呼び出しを消すPRを作った。 RBSのメモリ使用量を減らす前準備。


github.com

RBSのメモリ使用量を減らすために色々やっているのだけど、計測用にベンチマークスクリプトを毎回書いているのは面倒なので、rbsリポジトリに追加するPR。


Cを書いていて、謎のセグフォが出てそこそこ悩んだ。雰囲気は次のようなコード

#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int id;
  int value;
} entry;

typedef struct {
  int len;
  int cap;
  entry entries[0];
} table;

table *table_new(int cap) {
  table *t = malloc(sizeof(table) + sizeof(entry) * cap);
  t->len = 0;
  t->cap = cap;
  return t;
}

int main(void) {
  table *t1 = table_new(1000);
  for (int i = 0; i < t1->cap; i++) {
    t1->entries[i].id = i;
    t1->entries[i].value = i * 10;
    t1->len++;
  }

  table t2 = *t1;
  printf("t1 last value: %d\n", t1->entries[t1->len-1].value);
  printf("t2 last value: %d\n", t2.entries[t2.len-1].value);

  return 0;
}

t1もt2も同じstructなので同じ値が出力されると思いきや、私の手元だとt2`を出力するところでセグフォが出てしまう。

t1 last value: 9990
zsh: segmentation fault  ./a.out

この問題に最初遭遇したときは、t2の方の書き方だけをしていたので、セグフォの原因がさっぱりだった。 その後t1の書き方をすると解決することに気がついたのだけど、「えっ->(*v).ってsyntax sugerの関係なんじゃないの??」としばらく理解ができていなかった。

これの答えが何だったかと言うと、構造体をコピーしていることが原因だった。

まず、entry entries[0] の部分が影響している。これは可変長構造体、みたいな用語(正確な用語は知らない)のテクで、メモリ使用量を抑えるのに便利。 https://satosystems.hatenablog.com/entry/20100916/1284637817 とかを参考にしていた。

これは構造体の直後のメモリ領域に配列のためのメモリ領域を確保して、構造体に配列へのポインタをもたせることなく可変長の配列を実現している。便利。

ところが、table t2 = *t1;t1 を別のローカル変数であるt2にコピーしている。ということは、このt2が保存されているアドレスはもともとmallocしてきたアドレスとは異なるということ。t2.entriest2の直後の領域を参照しようとして、セグフォになってしまっていた。

2024-03-28

github.com

rspec-request_describer に PR をしていた。

RSpeccontext を差し込むところを間違えたら、rspec-request_describer 内部でエラーが起きていてエラーの意図を掴むのにちょっと手間取ったので、エラーをハンドルしてどういうエラーなのか分かりやすいようにしてみた。巨大describeになってくるとインデントが迷子になりがち。

速攻マージ&リリースされたので、迷子になりがちな人はアップデートすると良さそう。


最近(といっても数ヶ月前からだけど)は、ピアノで海の見える街を練習している。ピアノのやる気に満ち溢れている期がやってきたので、割と進捗が良い。

曲のイメージをもうちょっと膨らませたくなって、魔女の宅急便の映画を見たりもした。配信がなくて、仕方なくDVDを買った。

2024-03-26

TOEIC IPテストを受けた。860点。

前回から20点下がったが、ツイートにもある通り大きな差ではないので、前回がまぐれでなかった安堵のほうが大きい。

とはいえもうちょっと勉強していきたいなの気持ちでabceedを再開した。

前回受けたのは半年ぐらい前だったかなーと思っていたので、1年も経っていたのはちょっとびっくりした。

ちなみに点数の推移は、680点(2022-04-12), 795点(2022-12-01), 880点(2023-03-01), 860点(2024-03-26)となっている。次は900超えたいなー


www.amazon.co.jp

「追放されたチート付与魔術師は気ままなセカンドライフ謳歌する。 ~俺は武器だけじゃなく、あらゆるものに『強化ポイント』を付与できるし、俺の意思でいつでも効果を解除できるけど、残った人たち大丈夫?~」を最近読んだ。

「あーはいはいよくある追放ものね」と思っていたら、完全に異常で良かった。なろう系だと思わず異常漫画だと思って読んでみるのをめっちゃおすすめ。

2024-03-20

github.com

github.com

activerecord-originator の型定義周りを軽く修正していた。

型の変更しか入っていないけれど、v0.2.1をリリースした。


github.com

graphql-coverage でも同様の型の修正をしていた。


github.com

graphql-coverage を久々にいじっていたら、新しいRubyのバージョンでCIが走っていなかったので有効にした。

2024-03-19

activerecord-originator、ここ数日毎日数件海外の人っぽいstarが増えているのだけど、どこからこれが見つけられているのかがさっぱりわからない。 もっと海外にリーチしていきたいのでヒントがほしい…

2024-03-16

github.com

github.com

activerecord-originatorベンチマークスクリプトを追加した。

これを追加したことによって、どの程度パフォーマンスが劣化しているかが分かった。単純に#to_sqlを呼び出す場合で3倍ぐらい、実際にselectクエリを発行する場合でも2倍ぐらいの速度差が出ていた。クエリを発行しているのはメモリ上のsqliteだし、レコードも100件しか作っていないからあまり現実的な比較ではない。


github.com

activerecord-originatorの速度改善をした。今まではすべてのNodeを拡張してinitialize時にcallerを保存していたのだけど、これをクエリに位置情報を差し込みたいNodeだけ拡張するようにした。

これによって、#to_sqlは71~78%程度、クエリの実行は84~86%程度の速度劣化に抑えられた。

これだけ速度劣化が小さく出ていれば、実アプリケーションに入れたときの速度差は気にならないぐらいになっていそう(たぶん)。単純なクエリ実行の例だと、1回あたり0.02ミリ秒しかオーバーヘッドが乗ってない計算になりそう。

この変更を入れたのでv0.2.0をリリースした


github.com

そういえばIS NULLとかを考えていなかったな、と思ってテストを書いてみたら、特に何もせず通って便利だった。 すでに実装は済んでいたけど、テストがあったほうが後々嬉しくなる可能性がありそうなのでテストだけ追加した。


where("title LIKE ?", "%#{title}%") みたいなやつの対応を考えていたのだけど、むずそう。

これはSqlLiteral nodeとして扱われるのだけど、このNodeが特殊で、どうやら作られるタイミングは#whereが呼ばれるタイミングではなく#to_sqlが呼ばれるタイミングっぽい。それだとこのnodeのinitializeにhookしてもほしい位置情報が取れなくて困る。

いい解決方法あるかなあ。あんまり思いつかない。whereメソッドを上書きして…とかやればできるだろうけどやりたくないよねえ