在 Hacker News 的最新列表上面看到的演算法,用來計算圓周率 π 的公式:「Bellard's formula」。
這個公式特別的地方在於 的部份,這使得整個公式可以很迅速的算出某個二進制位置上的值 (要做一些條件判斷,相較於十進制轉二進制的方式快多了),而且可以馬上想到一些平行運算的方式...
另外一個讓我注意到的點是,這居然是 Fabrice Bellard 丟出來的公式,真的是到處看到他的蹤跡耶...
幹壞事是進步最大的原動力
在 Hacker News 的最新列表上面看到的演算法,用來計算圓周率 π 的公式:「Bellard's formula」。
這個公式特別的地方在於 的部份,這使得整個公式可以很迅速的算出某個二進制位置上的值 (要做一些條件判斷,相較於十進制轉二進制的方式快多了),而且可以馬上想到一些平行運算的方式...
另外一個讓我注意到的點是,這居然是 Fabrice Bellard 丟出來的公式,真的是到處看到他的蹤跡耶...
前陣子的「為資料庫提案新的 UUID 格式」這邊提到了有人提案要增加新的 UUID 格式,Percona 的老大 Peter Zaitsev 在 Twitter 上貼了「UUIDs are Popular, but Bad for Performance — Let’s Discuss」這篇在 2019 年時他們家的文章,題到了 MySQL 使用 UUID 當作 Primary Key 的事情:
UUIDs are Popular, but Bad for Performance — Let’s Discuss
https://t.co/2ulSGPB77L— Peter Zaitsev (@PeterZaitsev) August 21, 2021
要注意的是這篇文章沒有要從頭解釋 UUID 對於 Primary Key 的壞處,如果你想要先了解的話,在這篇文章的開頭給了一堆其他文章的連結,裡面就有討論過了。
這篇主要是在討論,如果硬要用 UUID 當 Primary Key 時,可以有什麼方法降低對 InnoDB 的衝擊,剛好回應最近的提案。
開頭還是先花了一些篇幅大概講一下 UUID 的種類,然後在「What is so Wrong with UUID Values?」這邊提到了字串比較的差異,如果 UUID 是到最後一碼才不同的話 (這邊是跑 df878007-80da-11e9-93dd-00163e000002 與 df878007-80da-11e9-93dd-00163e000003 與比較一億次):
1 row in set (27.67 sec)
但如果是一開始就不同的話 (這邊是選擇 df878007-80da-11e9-93dd-00163e000002 與 ef878007-80da-11e9-93dd-00163e000003) 會快很多:
1 row in set (2.45 sec)
但如果與數字相比的話 (這邊是 2=3
這樣的條件去比):
1 row in set (0.96 sec)
可以看數字在這邊的優勢,另外也是在說明,如果你用的是 time-based ordering 的 UUID,要考慮會遇到這個可能會發生的效能問題。
再來是玩 UUID 的三種不同的儲存方式對於寫入效能的差異,分別是 CHAR(36)
(32 bytes 的 hex 加上四個 -
)、base64
(用 CHAR(22)
存) 與 BINARY(16)
,可以看出來 BINARY(16)
因為佔用空間比較小的關係,是可以高速寫入持續最久的,再來是 base64
,最差的是 CHAR(36)
:
後面給了兩個 workaround,第一個算是定義了另外一種產生 128 bits 的方式,第二個則是想辦法把 UUID 對應到數字。
這在 MySQL 的環境裡面算是被討論的很久的主題了。(我猜在 PostgreSQL 應該也是,不過 PostgreSQL 的社群沒跟那麼久...)
以前有人曾經定義過十六進位的英語念法... 當作是歷史在看 XD
Who knew there was a sort of hanky code for hexadecimal. Thanks Datamation magazine from 1968 #prelingerwiki pic.twitter.com/WHj5x0Bm5o
— Liz Henry (@lizhenry) August 25, 2019
在 Twitter 上看到這樣的說明:
$ cat p.php
<?php var_dump(md5('240610708') == md5('QNKCDZO')); ?>
$ php p.php
bool(true)
Please start using "===", thx. @tkh16
— Joshua Wright (@joswr1ght) December 15, 2014
原因出自:
php > var_dump(md5('240610708')); string(32) "0e462097431906509019562988736854" php > var_dump(md5('QNKCDZO')); string(32) "0e830400451993494058024219903391"
施主,這 hex 與科學表示法好雷啊...
每次都忘記,寫一篇之後查比較方便... 重點在對 xxd 的變化應用,而 xxd 被包在 Vim 裡,所以應該都會裝... 吧...
xxd 預設是把 binary 轉成 hex,但你可以用 -r
參數變成反向,也就是 hex 轉 binary。
所以剩下的就很簡單了,先把 hex 轉成 binary 再轉成 base64:
echo 0123456789ABCDEF | xxd -r -p | base64
這邊有裝 Base64 所以可以直接用,如果沒有的話,可以用 OpenSSL 替代:
echo 0123456789ABCDEF | xxd -r -p | openssl enc -base64