お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

三年位前だろうか、まだコロナが猛威を振るっていたころの話だ。私は自転車で街を走っていて一つの街頭広告を見かけた。『手洗いに「解除」はありません。』という文字が書かれ、柔らかなテイストで家族のイラストが描かれたシンプルなものだった。広告主は牛乳石鹸で、その時私は「確かにそれはそうだ。しかし石鹸なんて使わなくなったな」と思っていた。この広告は今でも同じ場所に掲示され続けており、通る度に眺めては物思いにふけっていた。

そしてつい先日ホームセンターに行った時のことだ、レジの前で牛乳石鹸の特売がされていた。「ふーん、石鹸かぁ…」と思い、買うか悩んだがレジに並んでいたので判断しきれず、その時は買わずにいた。

翌日である今日になり、石鹸を使ってみるのも悪くないのではないか?と思い、早速買ってみることにした。理由としては石鹸の方が安く済みそうだと思ったからだ。というわけで牛乳石鹸の赤箱と石鹸皿を買ってきた。石鹸皿はコーナンにあったアスベル エミール 石けん皿 ホワイトだ。汁受けがついているので石鹸のぬめりをキャッチできるのがいい。全く今風ではない古臭い作りだが、これでいいのだ。

今回購入した牛乳石鹸の赤箱。国産の文字がまぶしい。石鹸皿も買った
個包装は牛の絵が描かれた懐かしいパッケージだ
石鹼皿の上に乗せた牛乳石鹸。今回買ったのは大きめの品だったが無事乗った。石鹸に描かれた牛のエンボスが良い

私は長らくボディーソープを使っていた。何故なら石鹸は使い辛く、古臭いと思っていたからだ。ボディーソープは使いやすくモダンだと思っていたので使っていた。昔の私は新しいものが好きで、新しいものにすぐ飛びつく癖があった。よく近所の人からも「君は進みすぎている」と言われたものだ。

ボディーソープを使うときは十分に泡立たせるために二回ほどプッシュすることが多く消費量が多いのが悩みだった。また替えのリフィルも場所を取るし、ごみが多い。取り換え時に抜いたポンプから中身が垂れてきて汚れるのも好きでなかった。

しかしそれらの課題は石鹸なら解決できるのではないかと思ったのだ。石鹸はコンパクトで場所を取らないし、それだけにごみも少ない。何なら私は今、新聞を購読していて紙ごみはリサイクルに出せるので、環境保全の意味でもよい。ボディーソープのリフィルもリサイクル出来るはずだが、する気が起きない。しかもなくなった時の詰め替え作業も不要だ。ついでに言うと軽い。記憶が確かなら石鹸は中々減らないので長持ちするので節約になるし、買いに行く手間が省けるのはいいことだ。また、ボディーソープと違って残量がわかりやすいのも利点だろう。ボディーソープはある日突然出なくなって困ることがあるが、石鹸は小さくなったら買いに行けばいいだけだ。常にストックしておく必要はないし、ストックしておくにしてもボディーソープのリフィル一本分の面積に10個くらい置けるのも魅力といえる。

実際に使ってみた感じも手に取って何度か揉めば十分に泡立ったので、ポンプを押して更に泡立てるという工程がなくなり楽になった気がする。何より石鹸をこねくり回すのは新鮮で楽しい。しかも顔まで行けるので、フェイスソープが要らなくなった。

牛乳石鹸を買うときは色は青と赤で少し迷ったのだが、乾燥肌が辛いなど最近肌に関するトラブルに絶えないので赤にすることにした。子供のころは赤い牛乳石鹸といえば高級品というイメージだったし、実際赤の方が高いのだが、ボディーソープと比べたら些細な価格なのでどうでもいい話だ。

今まで使っていたボディーソープだとリフィルが400円程度するが、牛乳石鹸の赤い奴は3つ入りで300円程度、1個辺り100円くらいである。どう考えてもこちらの方が安い。しかも牛乳石鹸は大阪の会社なので、地産地消的な意味合いでもよい。

「SEA BREEZE ボディシャンプー クール&デオドラント」という非常に長く覚えきれないので買い替えに地味に難儀する商品名から、「牛乳石鹸の赤箱」という非常に明快な商品になったのも買い替え時にありがたい。SEA BREEZEはシリーズ商品が結構あり、毎回これで合ってたっけ…?となりがちなのがよくない。いや、もう色で覚えたが。他にも売っている店があまり多くないのも悩みだった。牛乳石鹸なら大抵の店にあるだろう。

因みに牛乳石鹸の箱にはSOAPと書かれており、固形だから石鹸、液体だからソープという話ではないらしい。そういえば昔は液体のやつをボディーシャンプーとか言ってた気がしなくもない。また、赤箱は関西向け、青箱は関東向けだったらしい。近所で赤箱の方が青箱より売れてそうだったのはそこにも理由があるのかもしれない。

しかし変革シリーズも第五弾となった。思えばWordPressからadiaryの乗り換えも変革シリーズにしてしまってよかった気がする。

デスクトップにアイコンを表示させる

何故か標準ではアイコンが出てこないが、これをすることでデスクトップでファイル操作ができるようになる

  1. アクティビティを開き、「ex」と打ち、拡張機能を開く
    アクティビティを開き、「ex」と打ち、拡張機能を開く
  2. Desktop Icons NG (DING)をONにする
    Desktop Icons NG (DING)をONにする

日本語のフォルダ名を英語化する

/home/hoge/デスクトップみたいなパスを/home/hoge/desktopに変える方法

以下のコマンドを流す。

env LANGUAGE=C LC_MESSAGES=C xdg-user-dirs-gtk-update

Node.jsとGoogle Chrome, Microsoft Edgeを用いて、try-catchとif文でエラー処理にかかる時間がどのくらい違うのかを調べた。

計測手法

次の4パターンを100万回実行した結果を記載している。

  1. Result型としてエラーオブジェクトをreturnし、if文で判定する方式
  2. Result型としてエラーインスタンスをreturnし、if文で判定する方式
  3. エラーオブジェクトをthrowし、try-catchで判定する方式
  4. エラーインスタンスをthrowし、try-catchで判定する方式

確認に使用したコード:https://gist.github.com/Lycolia/304bc9e825e821c2d582f3ef9f700817

計測結果

CPUによって処理速度がかなり変動するが、いずれの環境でも処理速度の速さは以下の通り。

  1. Result型としてエラーオブジェクトをreturnし、if文で判定する方式
  2. エラーオブジェクトをthrowし、try-catchで判定する方式
  3. Result型としてエラーインスタンスをreturnし、if文で判定する方式
  4. エラーインスタンスをthrowし、try-catchで判定する方式

計測に使用したCPU

CPU コア スレッド クロック L2キャッシュ L3キャッシュ
Intel Core i7 13700 16 24 5.20GHz 24.00MB 30.00MB
Intel Core i7 1265U 10 12 4.80GHz 6.50MB 12.00MB
AMD Ryzen 5 5600G 6 12 3.90GHz 3.00MB 16.00MB

Intel Core i7 13700端末

16C24T, 5.20GHz, L2 24.00MB, L3 30.00MB。ミドルタワーPC。

Node.js v16.20.2

処理環境

Env Ver
CPU Intel Core i7 13700
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 802
Result型としてエラーインスタンスをreturnし、if文で判定する方式 5,942
エラーオブジェクトをthrowし、try-catchで判定する方式 1,847
エラーインスタンスをthrowし、try-catchで判定する方式 6,527
Node.js v18.19.1

処理環境

Env Ver
CPU Intel Core i7 13700
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 887
Result型としてエラーインスタンスをreturnし、if文で判定する方式 5,826
エラーオブジェクトをthrowし、try-catchで判定する方式 2,006
エラーインスタンスをthrowし、try-catchで判定する方式 6,464
Node.js v20.11.1

処理環境

Env Ver
CPU Intel Core i7 13700
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 720
Result型としてエラーインスタンスをreturnし、if文で判定する方式 5,375
エラーオブジェクトをthrowし、try-catchで判定する方式 1,690
エラーインスタンスをthrowし、try-catchで判定する方式 5,978
Microsoft Edge 121.0.2277.128

処理環境

Env Ver
CPU Intel Core i7 13700
OS Windows 11 Pro 22H2(22621.3155)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 4,246
Result型としてエラーインスタンスをreturnし、if文で判定する方式 12,329
エラーオブジェクトをthrowし、try-catchで判定する方式 11,985
エラーインスタンスをthrowし、try-catchで判定する方式 14,105
Google Chrome 122.0.6261.58

処理環境

Env Ver
CPU Intel Core i7 13700
OS Windows 11 Pro 22H2(22621.3155)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 3,507
Result型としてエラーインスタンスをreturnし、if文で判定する方式 10,793
エラーオブジェクトをthrowし、try-catchで判定する方式 10,482
エラーインスタンスをthrowし、try-catchで判定する方式 12,452

Intel Core i7 1265U端末

10C12T, 4.80GHz, L2 6.50MB, L3 12.00MB。ノートPC。

Node.js v16.20.2

処理環境

Env Ver
CPU Intel Core i7 1265U
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 972
Result型としてエラーインスタンスをreturnし、if文で判定する方式 11,416
エラーオブジェクトをthrowし、try-catchで判定する方式 2,288
エラーインスタンスをthrowし、try-catchで判定する方式 13,993
Node.js v18.19.1

処理環境

Env Ver
CPU Intel Core i7 1265U
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 1,102
Result型としてエラーインスタンスをreturnし、if文で判定する方式 11,333
エラーオブジェクトをthrowし、try-catchで判定する方式 2,441
エラーインスタンスをthrowし、try-catchで判定する方式 12,827
Node.js v20.11.1

処理環境

Env Ver
CPU Intel Core i7 1265U
OS Ubuntu 20.04.6 LTS (WSL2)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 888
Result型としてエラーインスタンスをreturnし、if文で判定する方式 10,881
エラーオブジェクトをthrowし、try-catchで判定する方式 2,269
エラーインスタンスをthrowし、try-catchで判定する方式 12,254
Microsoft Edge 121.0.2277.128

処理環境

Env Ver
CPU Intel Core i7 1265U
OS Windows 11 Pro 22H2(22621.3155)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 7,526
Result型としてエラーインスタンスをreturnし、if文で判定する方式 34,761
エラーオブジェクトをthrowし、try-catchで判定する方式 39,005
エラーインスタンスをthrowし、try-catchで判定する方式 65,752
Google Chrome 122.0.6261.58

処理環境

Env Ver
CPU Intel Core i7 1265U
OS Windows 11 Pro 22H2(22621.3155)

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 6,303
Result型としてエラーインスタンスをreturnし、if文で判定する方式 16,460
エラーオブジェクトをthrowし、try-catchで判定する方式 17,979
エラーインスタンスをthrowし、try-catchで判定する方式 23,378

AMD Ryzen 5 5600G端末

6C12T, 3.90GHz, L2 3.00MB, L3 16.00MB。ミニタワーPC。

この端末はOSがUbuntuであるため、これまでのWindows環境との単純比較はできない。

Node.js v16.20.2

処理環境

Env Ver
CPU AMD Ryzen 5 5600G
OS Ubuntu 22.04.3 LTS

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 1,786
Result型としてエラーインスタンスをreturnし、if文で判定する方式 11,242
エラーオブジェクトをthrowし、try-catchで判定する方式 3,880
エラーインスタンスをthrowし、try-catchで判定する方式 12,716
Node.js v18.19.1

処理環境

Env Ver
CPU AMD Ryzen 5 5600G
OS Ubuntu 22.04.3 LTS

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 1,933
Result型としてエラーインスタンスをreturnし、if文で判定する方式 11,094
エラーオブジェクトをthrowし、try-catchで判定する方式 3,839
エラーインスタンスをthrowし、try-catchで判定する方式 12,767
Node.js v20.11.1

処理環境

Env Ver
CPU AMD Ryzen 5 5600G
OS Ubuntu 22.04.3 LTS

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 1,714
Result型としてエラーインスタンスをreturnし、if文で判定する方式 10,741
エラーオブジェクトをthrowし、try-catchで判定する方式 3,444
エラーインスタンスをthrowし、try-catchで判定する方式 11,978
Microsoft Edge 121.0.2277.128

処理環境

Env Ver
CPU AMD Ryzen 5 5600G
OS Ubuntu 22.04.3 LTS

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 4,348
Result型としてエラーインスタンスをreturnし、if文で判定する方式 21,584
エラーオブジェクトをthrowし、try-catchで判定する方式 15,543
エラーインスタンスをthrowし、try-catchで判定する方式 23,119
Google Chrome 122.0.6261.57

これだけバージョンが合わなかった。

処理環境

Env Ver
CPU AMD Ryzen 5 5600G
OS Ubuntu 22.04.3 LTS

処理結果

処理方式 処理時間(ms)
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 4,842
Result型としてエラーインスタンスをreturnし、if文で判定する方式 16,607
エラーオブジェクトをthrowし、try-catchで判定する方式 15,051
エラーインスタンスをthrowし、try-catchで判定する方式 18,095

全体サマリ表

凡例

  1. Result型としてエラーオブジェクトをreturnし、if文で判定する方式
  2. Result型としてエラーインスタンスをreturnし、if文で判定する方式
  3. エラーオブジェクトをthrowし、try-catchで判定する方式
  4. エラーインスタンスをthrowし、try-catchで判定する方式

サマリ画像

CPUによってかなり差が出ているが、Intel CPUの13700と1265Uを比較した場合、例外を作らない1, 3のケースでは処理に大きな差がないが、例外を作る2, 4のケースでは有意な差が認められるので、モバイル向けとデスクトップ向けでCPUの処理効率に差があることがわかる。

AMD CPUと比較した場合、Node.js環境で例外を作らないケースではIntel CPUに大きく引けを取るが、ブラウザ上でのそれではパフォーマンスは高い。また例外を作るケースでもNode.js・ブラウザ共にIntel CPUと比較した場合のパフォーマンスが比較的よいという、面白い結果になっている。但しOSが違うことの影響もあるため、単純比較はできないが…。

あとがき

ひとまずtry-catchを使うと遅くなるということが確かめられたので良かったし、環境によって劇的遅くなるケースがあるというのは思わない収穫だった。

これを試そうと思った切欠はtry-catchが乱用されているコードを見てパフォーマンス劣化に繋がっているのではないかという疑問を抱いたからだ。try-catchでパフォーマンスの劣化が起きることは知識としても経験としても知っていたのだが、ちゃんとレポートしたことがなかったので今回まとめてみた。

try-catchの利用によりパフォーマンスの劣化が起きるというのは、古い時代にあった開発のお作法を知っている人であれば、それなりに常識だとは思うが、最近は知られていないか、知られていても意識していないことが少なくないと思われるので、今回記事にしてみた感じだ。

100万回の実行なので細かい話になるとは思うがパフォーマンスチューニングは細かいことの積み重ねでもあるので、むやみやたらに例外を使わないことは重要だと思う。そもそも例外は制御しづらいので、可能な限りif文で処理を書くことが望ましいだろう。

処理が遅延する原因としては二つあると考えていて、一つは例外生成時に顕著であることからスタックトレースの生成を初めとしたエラーオブジェクトの生成に時間がかかっているのと、もう一つはcatchでも遅延が出ることから、コールスタックから最寄りのcatchを辿るのに時間を取られていると思われる。今回の検証では特に出してないが、以前確認した時の記憶が確かであれば、catchに入らない限り、tryだけで顕著に処理が遅延することはなかったと思う。

あと、どうでもいいことだがconsole.log()で結果を出したときにEdgeだけObjectのKeyの順序が他と違ったので転記しているときに微妙に不便だった。何回やっても同じだったので恐らくEdgeだけキーをソートするアルゴリズムが違うのだと思う。まぁObjectとかHashとかMapとかDictionaryみたいなやつは順序が保証されないので別にいいっちゃいいんだけど、まさか実装によってソート方式が違うというのは思いもしなかった。

EdgeとChromeで処理結果が優位に違うのも、恐らくこれが原因なのだろう。分からないが多分JSのエンジンの実装が違う気がする。

それとLinuxのEdgeにはマウスジェスチャー機能がないという悲しいことも分かった。

参考

投稿日:
サービス::Last.fm

私は楽曲購入にAmazon.co.jpを利用していて、CDではなくMP3で購入しているのだが、プリセットされているタグがLast.fm向きではない問題に時折苦しめられている。例えばタグの内容で大文字小文字や全角半角が違うとか、最悪文字そのものが違うケースもある。そうなるとLast.fmのScrobblingに支障が出ることがあるので、タグの編集を行うことがある。

この記事ではその一連の流れを紹介する。

タグ編集

私はAIMPというロシア製の音楽プレイヤーを使っているので、これに付属してるAIMP Advanced Tag Editorを利用する。これは下図のように、AIMPメニューから辿ることで開くことができる。

AIMP Advanced Tag Editorの開き方

楽曲があるフォルダまで移動し、タグを編集する。

AIMP Advanced Tag Editorを使ったタグ編集方法

Last.fmに合わせたいので、Last.fmのタグ情報を適用する

Last.fmのタグ情報を適用する方法

ついでに過去に再生したもので、Scrobbleされた内容を今回編集した内容に合わせたい場合だが、この場合はLast.fmのSubscriber(課金ユーザー)になる必要がある。Subscriberの料金は一月$3.00で、非継続課金も選べるので使いたい時だけ課金できるのが便利だ。

課金ユーザーになったら次はLast.fmで自分のページを開き、Libraryから修正したいScrobbleを探す。

自分のLibraryページ

修正したいScrobbleを選択するとメニューボタンが生えてくるので、そこからメニューを開きScrobbleを編集する。

メニューからScrobbleを編集する

以下のようなダイアログが出てくるので、さっき打ち直したタグ情報を入れるといい感じになる。また、この際に下図赤枠で囲ったBulk editにチェックを入れると、その曲の全てのScrobbleを一括編集できるので便利だ。

Scrobble編集画面

以前WordPressで構築していたサイトが頻繁に落ちていることについて記事にしたが、adiaryに変えてからどうなったかというと、恐らく落ちなくなったと思う。

何故そう思ったかだが、今までGoogleにインデックスさせるときは毎回Search Consoleから手動登録していたが、そんなことをしなくても勝手にインデックスしてくれるようになったからだ。BingにもIndexNowを使わずとも勝手にインデックスされている。いや、BingのクローラーについてはIndexNowの有無による差を検証したことがないので有意に改善しているかは正直不明だが…w

少なくともこれでインデックスされやすくなり、以前よりアクセスしやすくなることだろう。読み込み時間が0.3秒変わるだけでブラウザバックが減るとかいう話も昔どっかで読んだ気がするし、0.3秒どころか6秒くらい改善してそうなので、効果はかなり期待できると考えている。

Markdownのレンダリングについても作者に要望を出しまくったので大分改善した。とはいえ、まだ問題点は残るので、そこはMarkdown parserを自作する事で上手いことやっていきたいと思う。結果としてadiaryへの乗り換えは大成功だったといえる。

adiaryは非常に素晴らしいCMSだと思うので、WordPressを使っていて重さに悩む人や、CDNなどの費用を節減したい人は検討されてもいいのではないだろうか?WordPressのように素晴らしいテーマや有益なプラグインは存在しないが、なければ作ればいいので、そういう気概のある人には非常にお勧めできると思う。

また本体やプラグイン、テーマが勝手にアップデートされることがないので「何もしてないのに壊れた」が起きないのもいいところだ。当然、その分の保守能力はサイト管理者に求められるが、本来ホームページ運営というのはそういうものである。一定のリテラシーがないとできないのは当然のことだ。少なくとも昔のインターネットでは常識だった筈だ。

何よりこのCMSは日本製だ、日本人なら日本製に拘ってみるというのもありだろう。

改善の余地は山ほどあると思うので、最近開発から遠ざかっていた人にも大変お勧めできる。adiaryはOSSなので、コントリビュートするのもよし、フォークするのもよしだ。逆にシンプルで複雑さがないので、これで必要十分というケースもあるだろう。

この機会に昔懐かしいPerlに触ってみるというのも一つの経験になるだろう。かつてCGIを書いていた人も、使っていただけの人も、どっちでもない人も、Perlという言語の魅力に触れてみたり、新しく発見してみる一つの機会になると思う。Perlの言語仕様はもしかしたら余り良くはないかもしれないが、夢中になって書いていれば、そんな言語でも新しい発見があったりして、きっと楽しいと思う。

いろんな意味で自分のホームページを作るという意味では非常に良いCMSだと思うので、私はそこが好きだ。

余談だが記事ID「0268」以降がadiaryの記事で、それ以前がWordPressの記事となる。厳密にいうとWordPressの記事の中には、はてなダイアリーやQiitaで書いた記事も入っているのだが、区別する術がないのでWordPressの記事ということで一緒くたにしている。特にない限りCMSの乗り換えはもうしないと思うので、この法則がずれることは恐らくないだろう。

因みに私がフォークしているバージョンでは暫定的にクリップボードの画像を直接アップロードできるように改造している。実験的な機能であるため動作保証などは一切しないが、もし画像が貼り付けられずに不便を感じる人がいたら使ってみてほしい。