カレーの恩返し

おいしいのでオススメ。

プログラミング以外の趣味を探した話

年末なのでポエムを書いてみようと思った。

プログラミングという趣味は一般社会に対してウケが悪く、属性が異なる初対面の人との話題に超困ったので他の趣味を探してみたよ、という話。
「プログラミングが趣味で何が悪い、ウケを気にして趣味を探すことがそもそも間違っている」といった議論をする気はない、と一言添えておきます。

プログラマは趣味もプログラミングの人が多いと感じる。 プログラミングと言ってもコードを書くことだけがプログラミングではなくネット記事・雑誌を読む、知人との議論による情報収集もプログラミングに含まれると考えている。

このサービスを作るとしたらどんな技術選択をするか、最近よく聞く言語/ライブラリを触ってみてどう感じたか、サービスを作る上でどんなことを大事にしているのかといった議論をするのは最高に楽しい。

自分もプログラミング以外の趣味はなく、「あなたの趣味/好きなことは何ですか?」と誰に聞かれると「コードを書いてなにか物を作ることです!」と答えていた。

もちろん世界中の人が「プログラミング」という趣味を面白がってくれるわけではないということは理解していたが、通っていた高専という学校の属性上あまり気にすることはなかった。*1

 

プログラミングという趣味は一般社会においてウケが悪い *2と気付いたのは知り合いがやっている居酒屋で定期的に行われているパーティに参加したときだった。

パーティでの会話
初対面の人「休みの日とかって何してるの?」
ぼく「コード書いたり技術系の記事読んだりすることが大半な気がします」
初対面の人「へー!すごい、ずっと勉強してるんだ」
初対面の人「そういうのじゃなくてどこか行ったりとか普通に遊んだりとかってしないの?」
ぼく「プログラミング以外?うーん、あんまりないですね...」

書いていると趣味関係なく自分が単純にコミュ障なだけではという気がしてきた。

どうやら「プログラミングは勉強だから遊びの内に入らない」と考えている人たちがいるらしい。 大学へ編入するため広島から関東へ拠点を移し色々な人と会うようになると、そのように捉える人たちに会う回数は増えていった。

高校へ行き大学へ進学した人たちが当たり前のように持っている「初対面の人と共通の話題を探しつつ会話を膨らませる能力」に対する強い憧れを抱くようになった。

「エンジニア属性を持たない人との共通の話題がなくて話が盛り上がらない」

この現状に危機感を感じた自分はプログラミング以外の趣味を探すことにした。

読書

とはいえどうやって探せばいいのか分からなかったため、小説を読み登場人物の趣味を参考にするという方法を考案し実践した。 (元々本を読むのは苦ではなかったというのも大きいのかもしれない)

しかし読んでいるうちに目的を忘れ単純に読書を楽しんでしまっていた。 が、読書は現在も継続できているので結果オーライ

最近はpaperwhiteを購入したため読書が加速している。

ダーツ

前からダーツが少し気になっていたので少し真面目にやってみようとマイダーツを買い、家の近くにあるダーツができる漫画喫茶に定期的に行くようにしてみた。

  • 肘のxyz座標を変化させない
  • 投げる時の手の軌道と肘が同一面上にあるか
  • リリースのタイミング

この3つのパラメータを調整し最適解を探索する計算機になった気分でやっていた。
自身をチューニングする感覚が新鮮で楽しかった、

ただ、だんだんと同じことの繰り返しに感じるようになり足が遠のいていった。 ある日ダーツをしている間は耳と頭が暇なことを発見したのでダーツしながらTech系Podcastを聞いたところ、体験がとても良かったのでなんとかまだ継続できている。

1,2時間くらい投げてると1,2本HAT TRICKが出るくらいになった。

美術館

「美術館行ってみない?」と友達に誘われたのがきっかけで美術館に行くようになった。それまでは美術館は行っても面白くないと思っていたが、一度予習して美術館に臨むと面白いことに気付いた。

漠然と作品を見て綺麗・荒々しいといった感想を持つのではなく、 作者が何を感じながら生き死んだのかを追体験するためのマイルストーンとしての作品、そう考えながら見ていると面白いと感じるようになった。

おそらく鑑賞する対象が作品から作者へ移ったからだと思う、
1人で行くときは音声ガイドを必ず借りる

 


 

現段階では読書・ダーツ・美術館が定番になっている。見返すとインドア且つソロで楽しめる内容に偏っていることに気付いた。まあいいだろう、突然アウトドアの趣味を探しても継続できないことは目に見えている。

もちろん定着しなかった趣味も存在する。

 

ウケが悪くない趣味を見つけるという本来の目的を達成したかどうかを確かめるには「初対面の人と話す」という検証フェーズが行う必要があるが、それは自分にとって多大なエネルギーを必要とするため現時点では実行に移せていない。

消費エネルギーが少なく、それなりのサンプル数を得るための効率的な方法としてはマッチングアプリがいいのかなあと思案している。同性のサンプルは得られないので別の方法も考える必要がありそうだけど。

 

そんな感じで2018年お疲れさまでした。来年もよろしくお願いします。

*1:高専在学中は「4学科もあるんだしそれなりに多様性あるよね」と思っていたが、卒業してから偏りがあったことに気付いた

*2:この記事で"ウケが悪い"とはそのネタを元に会話を膨らませる難易度が高いことを指す

Slackにアップしたスライドをいい感じに見れるやつ作った

これは呉高専 Advent Calendar 2018の23日目の記事です。

先日、kosen12sというコミュニティで発表した内容をつらつらと書いていきます。
スライドはこちら ↓

speakerdeck.com

なぜ作ったのか

自分が所属している研究室では毎週交代で最近読んだ論文をスライドにまとめて発表し合うイベントがあります。
とても良いイベントなのですが、現状として作ったスライドが共有されず「他の人が作ったスライドを見返せない」「自分が紹介するときに紹介済みの論文を載せていないか心配」という問題がありました。

以下のような脳内議論が行われた結果、、、


案1 : Slackにアップロードするよう声かけをすればよさそう?

Pros

  • Slackは研究室でよく使ってるのでアップロードは楽で良い

Cons

  • スライドを見返すのに使うのは難しい、整頓されていてほしい
  • スライドアップ時にキーワードも同時にpostすれば検索できるかもしれないけどSlackの検索のUXあんまり良くない(個人的感想)
  • 無料枠で使っているのでファイル容量を超えると古いファイルは削除されてしまう

案2 : speaker deck, slideshareにアップするよう声かけすればよさそう?

Pros

  • スライドが見やすく、検索しやすい
  • publicに公開するので自分のポートフォリオページとして活用できる

Cons

  • そこまで真面目にスライドを作り込んでないので心理的ハードルが高い
  • ページ開いてわざわざアップロードするのは面倒

 

Slackの特定のチャンネルにスライドをアップロードしたらシュッとweb上で公開されるランニングコスト0のツールがあればいいのでは?と思ったので作りました。

作ったもの

webページ(サンプル) → https://teppei-slides.netlify.com/

主な機能

  • アップロードしたスライドが一覧できる
  • スライドがキーワード検索できる
    • Slackでアップしたpdfのスレッドに書き込んでもらうことによりキーワードを設定
  • ユーザーのアイコンをクリックするとユーザーごとのスライドが見られる

リポジトリ

github.com

github.com

ざっくりとバックエンド、フロントエンドはこんな感じのツールで構成されています。

f:id:euglena1215:20181223154729p:plain

バックエンド

  1. GASがSlackの特定のチャンネルに新しいスライドがアップされていないか定期的に見に行く
  2. 新しいスライドがアップされていた場合、Google Driveにスライドを保存し直してスライド情報をスプレッドシートに保存する
    (Driveに保存し直しているのはSlackのファイル容量対策)
  3. GASがシートの内容をAPIとして公開する

フロントエンド

  1. GatsbyJSを使ってReactでページを作り、↑で作成したAPIを叩いて情報を取得し静的サイトを生成する
  2. netlifyを使ってwebページをホスティング

これら一連のフローで使っているツールは全て無料です。ほんといい時代ですよね。

GAS, GatsbyJS, netlifyなどのツールの説明はここでは割愛します。 スライドではめちゃくちゃ雑に紹介してるので初耳な人は↑のスライドを見てみてください。

がんばったところ

PDFの表紙画像の取得

表示画像の取得はスライド共有ツールを作るときに悩む問題で、この記事だとpdftocairoを使っています。

今回は無料の範囲という制約があるためGASで完結できるよう色々調べていると、 Slackはpdfをアップロードすると表紙の画像も取得できることを発見しました。

f:id:euglena1215:20181223191210p:plain

今回はこの機能を利用して表紙画像を取得しました。

余談ですが、Slackは画像をアップロードすると数種類のリサイズした画像も返してくれます。Slackは画像のリサイズ用SaaSとしてとても優秀です。

react-pdf-js で日本語が表示されない

PDF.jsをReactで使いやすくするためにwrapしてくれているreact-pdf-jsを使ってスライドの表示をしていたのですが、日本語が表示されないという致命的問題がありました。

原因としてはフォント情報が入っているcmapファイルのpathがPDF.jsにちゃんと届いてないという、PDF.jsを使った開発をしているときによく発生するあるある問題でした。

github.com

なのでreact-pdf-jsにPRを投げて修正しました。

研究室での普及活動

いくら頑張ってツールを作っても、作りっぱなしだと普及しないのは今までの経験から分かっていることなので

  • 使い方スライドを作ってアップロードする
  • 論文紹介の担当者にアップロードしてもらえるようDMで根回しをする

といった普及活動をしています。

まだ論文紹介の担当が1周していないのでもう少し普及活動は続けていく必要があるかなと思ってます。

 


 

こんな感じのツールがランニングコスト0&だいたい3日間くらいでできたのでほんといい時代だなと思いましたまる。

RailsのCookieStoreをnodeで復号する

背景

既に動いているRailsアプリケーションとfrontendの間にBFF用のnodeサーバを立てて、認証情報(currentUserIdの取得)はBFFで吸収させたい。

※ Session管理にCookie Storeを使っているRailsアプリケーションを想定しています。

書いた

RubyMarshal.loadRuby独自の機構なのでnode-marshalを利用した。

環境変数Railsアプリケーションで使っているSECRET_KEY_BASEを設定する必要がある。
expressのmiddlewareとして書いたので使うときは下のような感じになる。

import cookieParser from "cookie-parser";
import express from "express";

const COOKIE_NAME = "_sample_app_session_development"

// middleware
const app = express();
app.use(cookieParser()).use(setDecryptCookies(COOKIE_NAME));

参考にしました

encryption - How to decrypt a Rails 5 session cookie manually? - Stack Overflow
rails-cookie-parser/index.js at master · instore/rails-cookie-parser · GitHub

ISUCON8で予選敗退してきました

昨日、ISUCON8のオンライン予選があり予選敗退してきたのでその様子を報告します。

牛久大仏「う〜ん、顔採用w!」 というチーム名で筑波に編入した同期の@k5342, @chigichan24とISUCON8オンライン予選に参加してきました。

↓↓チームメンバーの記事はこちら↓↓

k5342.hatenablog.com

chigichan24.hatenablog.com

Rubyで参加しBest Scoreは5000点、最終Scoreは4000点と学生枠ボーダーには全然届かない点数でフィニッシュしました。

サーバはserver1: DB, server2: app1, server3: app2として利用し、
app1にベンチに来てもらい、ラウンドロビンでapp1とapp2にロードバランシングするといった構成になっていました。

スコアが目に見えて上がったのは複数台構成に変更したときくらいでした。

github.com

もちろんやってないこともたくさんあったけど、それなりに高得点者の歩いていた道を辿っていた気がするのでもう少し点数伸びてもよかったなぁというのが正直な感想です。


以下詳細です。

また、自分が関係するムーブだけ書いていきます(他のメンバーのムーブはブログに書いてくれるはず)

時刻 作業内容
前日
16:00 Redisの使い方をブログにまとめる→ これ
22:00 1台構成→複数台構成時に変えたときに起こりうる問題を色々考える
今まで1台構成でばかり解いていたので色々考えることがあることが分かって、色々調べた
当日
8:00
10:05 DBのschemaを確認する
10:30 自分のポートでwebサーバを立ち上げようとするが失敗する、ここで時間を多少消費する(firewalld周り)
11:30 reservationsのreserved_atにindexを貼ってみる
11:45 kataribe, myprofierを入れる(nginxに置き換え作業が発生していたため待ち時間が発生する)
←DBめちゃ重との連絡を受けたのでN+1を潰していくことにした
15:00 get_eventsから呼ばれてるget_eventのみ修正しN*N+1をN+1に改善した #6 
サクッと書いたクエリを「ほんまに合っとんかこれ?」と3人で悩む時間が発生していた(合っていた)。ここでかなりのタイムロスをした感がある
15:20 get_eventsのtransaction要らなくね?となったので外した #7
16:30 get_eventをN+1→1にした #8
クエリ自体は1になったけど処理方法がよくなかった(Array#selectでぐるぐる回しまくっていた)
17:00 開発に使っていたサーバからの移動を命じられ、いそいそと移動する
17:15 app serverのメモリがやべえという連絡を受け、メモリを節約できそうな場所を探すがよくわからん(残り1時間を切っていたのでget_eventを複数回呼んでいるところの修正は諦めた)
17:30 メモリ使用を減らすためにとりあえずSELECT *を消した、が終了直前だったのでマージは見送られた #10
17:45 app serverの再起動確認を行った&ベンチにenqueueされる様子を眺めていた
17:55 やることがなくなったので反省会開始
ISUCON終了
18:30 同じ場所でISUCONに参加していたluvtechno(カニオムライス), qnighy(カニオムライス), Altech(カニオムライス), gedorinku(winjisucon)と一緒に反省会会場(焼肉)へ移動
f:id:euglena1215:20180917115632j:plain:w450
↑反省し終わった(肉を撮り忘れていた)
Wantedly社員の人が反省会費用を出してくれた(特にCTO)!ありがとうございます!
22:30 つくばへ帰り反省会2次会(ラーメン)へ移動
ISUCON第2ラウンド開始
23:45 色々とやってないことはあったのでおもむろにPRを作り始める
f:id:euglena1215:20180917115924p:plain:w500
24:00 get_eventsでpublicなイベントだけ欲しい場合も一度全てのイベントを取得してからフィルタリングしていたのでSQLで行うように変更 #11
24:30 get_eventの修正後の処理がよくなかったので最適化した #12
25:20 get_eventをループ内で複数回呼んでるところ用にget_events_from_idsを作った、これが動けばN+1は全滅のはず #13
26:00 メモリが足りないとのことだったので不必要な変数の取り回しをなくした #14

おまけ

また、今回は自分のインターン先のWantedlyオフィスを会場として使わせてもらいました。

f:id:euglena1215:20180917123610j:plain

チームメンバーのうち1人は元インターン生、1人はWantedly全然関係ないという状況でしたが快諾してもらってありがとうございました!

f:id:euglena1215:20180917124431p:plain

所感

  • 初動が遅かった
    コードを書き始めたのが13:00ごろだった、このころには1万点弱に到達していたチームもちらほらいた気がする
  • 例年よりも作り込まれていてすごいと感じた
    フロントエンドはvue.jsで書かれていて時代の波を感じた
  • p debugよりもbinding.pryの方がやはり優秀
  • 帰ってからlocalで開発してみた結果、明らかにlocalで開発した方が実装速度が早いことが判明した(vim難しい)
  • 来年からは社会人として出るのでもっと力をつけていきたい

【ISUCON用】Redis Cheat Sheet

ISUCON予選が明日に迫ってきました。

Redisの操作が全く覚えられないのでまとめておきます。

セッティング

インストール

qiita.com

この辺とか見たらいい感じにできるのではないでしょうか(未確認)

使い方

# デフォルトは127.0.0.1:6379で繋がるはずなのでとりあえずこれで
def redis
   @redis ||= (Thread.current[:isu8_redis] ||= Redis.new(host: "127.0.0.1", port: 6379))
end

# keyはこんな感じでメソッドで隠してあげるとtypoが減ってよさそう
def redis_key_unread_count(channel_id)
  "isu7:unread_count:#{channel_id}"
end

# redisの操作もこんな感じでメソッドで隠してあげよう
def redis_increment_unread_count(channel_id)
  user_ids = redis_get_user_ids
  user_ids.each do |user_id|
    redis.hincrby(redis_key_unread_count(channel_id), user_id, 1)
  end
end

Redis豆知識

格納されているフォーマットについて

Redisには数値という概念がなく、一度全て文字列として格納されている。 (incrとかは文字列を数値に変換してから+1して文字列に戻すなどの操作をしているっぽい)

そのため、redis.get ...とかで取得した数値は毎回to_iする必要がある。

redis-cliでのデバッグ

  • とりあえず格納されているkeyを全部見たい
keys *
  • 一旦格納されてるデータ全部消したい
flushall

データ型

つらつら書いていこうかと思ったけどドキュメント見ればわかると思ったのでひとことに留めておきます。

String

標準的なkey value get, set, mget, mset, incr, incrby とかをよく使う気がします。

文字列型 — redis 2.0.3 documentation

# 使う可能性のあるコマンド一覧
SET(key, value)
GET(key) # なければnilを返す
GETSET(key, value)
MGET(key1, key2, ..., keyN)
SETNX(key, value)
MSET(key1, value1, key2, value2, ..., keyN, valueN)
MSETNX(key1, value1, key2, value2, ..., keyN, valueN)
INCR(key)
INCRBY(key, integer)
DECR(key, integer)
DECRBY(key, integer)

List

Listです。
両端からアクセスできる(rpush, lpush)けどisuconだとListは帯に短し襷に長し感があります。
Hashを使った方がいい場合の方が多そう。
idを保存しておいてllenとかでSQLのcountの擬似実装とかには使えるかも?

リスト型 — redis 2.0.3 documentation

# 使う可能性のあるコマンド一覧
RPUSH(key, string)
LPUSH(key, string)
LLEN(key)
LRANGE(key, start, end) # key, 0, -1 で全取得
LINDEX(key, index)
LSET(key, index, value)
LPOP(key)
RPOP(key)

Set

sorted setを使おう。setを使いたい場面ってisuconであんまり思いつかない。

セット型 — redis 2.0.3 documentation

Sorted Set

score付きのset。コマンド名に癖があるけどなんかすごい高機能。
DBのtableをそのままredisに載せようと思ったら

  1. Hashとしてそのままデータをredisに突っ込む
  2. Sorted Setでkeyをテーブル名、memberをhashのkey, scoreをDBのindexとして使う

みたいな感じになるんじゃないかな。(やったことない)
scoreの範囲を指定して取得とかできるので本当にtableと置き換えられる。
ただ、データの変形をせずにそのままテーブルの置き換えてパフォーマンスがどのくらい変わるのかはよく分かっていない。

ソート済みセット型 — redis 2.0.3 documentation

# 使う可能性のあるコマンド一覧
ZADD(key, score, member)
ZCARD(key) # memberの数を返す
ZSCORE(key, member) # 対応するmemberのscoreを返す
ZREM(key, member) # memberを削除
ZINCRBY(key, increment, member)
ZRANK(key, member) # 指定したmemberのスコア順にソートされた場合のindexが取得できる
ZREVRANK(key, member) # ZRANKの降順版
# indexで範囲指定してmemberを取得できる、WITHSCORESをつけると対応するscoreも取得できる
ZRANGE(key, start, end, [WITHSCORES])
ZRANGE(key, start, end, [WITHSCORES]) # ZRANGEの降順版
# scoreで範囲指定してmemberを取得できる。LIMIT, offsetも指定できるので実質SQL
ZRANGEBYSCORE(key, min, max, [LIMIT, offset, count, [WITHSCORES]])
ZCOUNT(key, min, max) # ZRANGEBYSCOREのCOUNT版

# 複数のsorted setから和集合、積集合を作る。共通するmemberのscoreは和をとる。
# ランキング計算とかするときにめちゃくちゃ便利なんだけど、複雑なので時間が余らないと使わない気がする?
ZUNIONSTORE(dstkey, N, k1, ..., kN, [WEIGHTS, w1, ..., wN], [AGGREGATE, SUM|MIN|MAX])
ZINTERSTORE(dstkey, N, k1, ..., kN, [WEIGHTS, w1, ..., wN], [AGGREGATE, SUM|MIN|MAX])

Hash

Hash。tableをそのままredisに持ってこようとするような荒技を使うときに使う。 操作方法自体はStringと大差ない。

ハッシュ型 — redis 2.0.3 documentation

# 使う可能性のあるコマンド一覧
HSET(key, field, value)
HGET(key, field)
HMSET(key, field1, value1, ..., fieldN, valueN)
HMGET(key, field1, ..., fieldN)
HINCRBY(key, field, value) # 負数を指定すればデクリメントもできる
HEXISTS(key, field)
HLEN(key)
HKEYS(key)
HVALS(key)
HGETALL(key)

雑にaxiosの便利ラッパー書いた

フロント書くときにaxiosが便利なのでよく使うんだけどHTTPメソッドごとで引数の型が若干違うので毎回忘れてググってる。

なので引数が同じになるようなラッパーに雑に書いてgistにあげておくことにした。
特に変なことはしてないのでコピペで使えるはず。

RailsCSRF対応済み

gista6599bb16d9999ecfccf457a7513e04d

RubyKaigi 2018に行ってきた【Day1】

まだ途中ですが、公開してから考えようと思います。

Keynote

f:id:euglena1215:20180605102252j:plain

ことわざの話

「名は体を表す」= 名前重要

ソフトウェアの世界には物理的制約がなく、概念で構成されているため名前はとても重要。
なのでソフトウェアエンジニアは概念に名前をつける必要がある。

1. 振る舞いに名前をつける

クラス、メソッド、変数に名前をつけるのがこれに該当
よく「メソッドの命名が難しい」と言うが、名前をつけるのが難しいのではなく十分に概念を理解できていないだけ
使う場面、機能を十分に理解していれば難しくない
なのでいい名前がついている機能は自然と良い機能・実装となる

Rubyにはyield_selfというメソッドがある

class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

何がしたいかという情報が入っていない
なので昨日コミットして新しいaliasを作った(matzがCRubyに機能面でコミットしたのは5年ぶりらしい!)
object.c: Add a new alias then to Kernel#yield_self · GitHub
thenという表現はmatzが推しているだけで他のRubyコミッターはみんな反対しているとのこと

2. プロジェクトに名前をつける

良い名前は求心力になる
例えばRuby
Rubyという名前をつけなかったら仙台に1000人以上集まってくれるような言語になってなかったんじゃないか
Rubyは良い名前付けだったなぁと思うが名前を付けたのは1993年の話
今つけるとしたらもっと違う名前をつけるかもしれない
今はググラビリティ(=Google検索時の単語のユニークさ)を意識した方がいい
悪い例としてGoやSwiftが挙げられる(www)
現代のプロジェクトの名前付けのトレンドとしては

  • 単語を組み合わせる(Ruby on Rails, tensorflowなど)
  • 既存の単語から1文字変えてみる
  • 変な単語を選ぶ(kaminari, hanami, kibaなど) ← 何をやっているのか分からないという弊害もある

名前はとても重要なので、良いプログラマーは名前つけにsensitiveであるべき

「時は金なり」= Time is Value

時間をどのように使うかが自分の人生を決定づける
プログラミングにおける時間は2つあると思っている

開発時間 ≒ エンジニアがPCに向かってる時間


Rubyは生産性が高い

  • 便利なメソッドがたくさんあるのでやりたいことはだいたい探せばある
  • 色んなフレームワークがある
  • Rubyを使っている人がたくさんいる
    • 個人の言語の選択基準は「近くに詳しい人がいる言語」を選ぶべき
  • (見かけ上)シンプルな構文

実行時間 ≒ コンピュータが処理する時間

パフォーマンスの話
Ruby 1.8以前は確かに遅かった
Ruby 2.6からはJIT compilerが入ったりとかなり改善されてきた
今まで言われ続けてきたconcurrency(=並列実行)もどんどん現実のものとなってきている
Ruby 3.0ではRuby 2.0の3倍速くなる
実行時間が短くなればサーバーのリソースを減らすことができて、その分が全て利益になる

「塞翁が馬」

人生の幸、不幸は予測できない=なにが起こるか分からない
1995-2004 Rubyを知らない人が多かった
2005-2012 普及し始め「Ruby is Great!」と言われるように
2013-2018 一時期の興奮が冷め安定期に入った
Rubyは死んだのか?という記事を目にするようになった
Rubyは毎年死んで毎年生まれ変わっている
Ruby is Dead Every Year
互換性は大事だが変化は止めてはいけない

RubyKaigiが「Rubyがもっとこうなったらいいなぁ」と考える機会になればいいなあと締めた。

Analyzing and Reducing Ruby Memory Usage

TODO: スライドを見つけたらまとめる

草生えるの人

feature cache Direct Isen - メモリをどのくらい使われているか調べる方法 - Reading code - Mall stack tracing - rubyは2つのヒープに分けられる - object space - allocation tracer - malloc stack logging :love: - プログラムがどのくらいメモリを使っているか - どこがメモリを食っているか - 誰がmallocしたのかが分からない - メモリ使用量を減少するパッチについて - feature cacheの最適化 - shared strings - 存在する文字列の添え字の調整で表現できるならそれで - 同じrequireは1度だけ - どうやって同じファイルとするのか? - 毎回requireされたかどうかチェックすると遅い - setupに時間がかかるようになる - key generation - ruby objectを消す - cacheを参照するときに生成していたruby objectを作成しないでよくする - rails アプリケーションのメモリ使用量4.2%減らせる - パッチを書く前にすでにないか調べてみよう - Stack VM - コード - AST - Linked List - Byte Code - Byte CodeはVMによって実行される - Linked List(T_NODE) -> ByteCode

puts “Hello World”

Hijacking Ruby Syntax in Ruby

www.slideshare.net Rubyの黒魔術を使ってfinal override abstract with deferといった他の言語にある機能を作ってみたよ、という発表。

使った黒魔術たち

Binding#local_variable_setはbindingした箇所でlocal変数を宣言できる
存在しない変数を定義したときはbindingのblockのスコープを抜けるとその変数定義は消える
存在する変数に対して定義したときはoriginalの変数定義を上書きする ← 🤔🤔🤔

ということは好きなところで変数の中身をいじれる!

TracePoint

ほぼ全てのイベントをhookに処理を走らせることができる

  • 行を移動したとき
  • raiseが発生したとき
  • classを定義したとき
  • returnしたとき…
  • bindingしたとき

これらの情報を合わせると コードの任意の箇所の変数を上書きできる!

refinements 前の記事を参照

euglena1215.hatenablog.jp

github.com

github.com

github.com

finalist, overrider, abstrikerで使われているMethod Hook

  • Module#method_added
  • Module#method_removed
  • Module#method_undefined
  • BasicObject#singleton_method_added
  • BasicObject#singleton_method_removed
  • BasicObject#singleton_method_undefined

Rubyはmethod定義の方法がたくさんあるため、このくらいMethod Hookをつける必要がある。 同じようなことをしようと思ったときは気をつけてねという話でした

TODO: 途中

All About RuboCop

TODO: スライドを見つけたらまとめる

英語が分からんぞ、、、

Fast Numerical Computing and Deep Learning in Ruby with Cumo

TODO: スライドを見つけたらまとめる

chainerの人 PFN Cumo

CUDA programming GPUはやい コア数の桁が違う 行列演算早い

CUDA GPUのメモリをallocate CPU メモリ -> GPU メモリ GPU側で計算 特徴 非同期になる GPU likes a job queue

Numo -> Cumoの文字列置換で動く element-wise operation 要素ごとの足し算 並列的に処理がしやすい reduction operation 和をとったりするやつ 並列かさせるのむずかしい 行列の積にも対応 cuBLAS

cudamallocが遅くなりやすい memory poolを使おう 一番簡単な実装は配列 best-fit hashのchain法かな? 基本はchain法、ほしいメモリサイズよりも大きいものが余ってたら切り出して利用する

rubyでは文字列評価によって行う

NumoよりCumoの方がめっちゃ早い 75倍早い

GPUGCと相性がよくないかも? mkmfの機能が足りない 第三のコンパイラの指定ができない broadcast operationが遅かった

すごそう +=のoverrideができない

A parser based syntax highlighter

speakerdeck.com

TODO: あとでまとめる

既存のhighlighterは正規表現で実装されている atomはcsonという形式で書かれてる

それの問題点は?

  • コードを読むのが辛い
    • 正規表現は難しい
      • 問題にぶつかったとき多くの人は正規表現で解決しようとするけど、問題が2つにふえる
  • highlightが完璧じゃない
    • トリッキーなコードを書いているとsyntax highlighterを倒すことができて
  • Iro
    • ripper based syntax highlighter
    • iro vs iro vim
      • iro vimがiroにデータを渡してiroで処理する
    • advantage iro
      • easy to read
        • parseはripperに任せている
      • ローカル変数をhighlightできる
      • parseがeditor依存じゃなくなる
    • implementation
      • Ripper.lex
        • tokenizeしていい感じに返す
          • 行番号と列番号
          • keyword, space, identify
          • その文字
          • lex state
      • Ripper.sexp
      • event driven

        - performanceのため