Skip to content

Zeroplex 生活隨筆

軟體開發和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

PHP copy-on-write 特性

Posted on 2016 年 10 月 23 日2021 年 3 月 12 日 By 日落 在〈PHP copy-on-write 特性〉中尚無留言

「copy on write」這個特性的意思是,在 variable 在沒有異動的時候,不會在記憶體中 re-allocate 一個新的區塊來存放資料,只有在被更新、修改或刪除資料時,才會另外將異動過的資料存放到記憶體其他區域。

剛看到時自己寫不知道這是什麼神奇的東西,看實例比較快。

先建立一個超級大的檔案 huge.log:

$content = file_get_contents('huge.log');

// 818.4 MB
echo sprintf("%.1f MBn", memory_get_peak_usage() / 1024 / 1024);

建立一個 function,這個 function 什麼事都不做,直接回傳我們傳進去的 $content:

$content = file_get_contents('huge.log');

function reply($content)
{
    return $content;
}

reply($content);

// 818.4 MB
echo sprintf("%.1f MBn", memory_get_peak_usage() / 1024 / 1024);

well … 我以前原本以為 pass by value,會另外將 variable clone 一份供 function 內部使用,但上面的 script 中呼叫了 reply() 以後,記憶體用量並沒有增加,所以將變數傳進 function 時,並沒有 clone 一份新的出來。

將原本的 reply() 稍做調整,在 return 之前新增一點東西到 $content 中:

function reply($content)
{
    return $content . 'some more';
}

reply($content);

// 1636.6 MB
echo sprintf("%.1f MBn", memory_get_peak_usage() / 1024 / 1024);

reply() 中對 $content 加了一些新的資料,這時候最大記憶體使用量就變為原來的 2 倍,很明顯 PHP 在記憶體 alloc 新的區塊來存放被修給過的 $content。所以「copy on write」的意思,就是這個資料被 write 時,PHP 才會要新的記憶體 (copy) 來存放有被修改過的資料。


處理大型資料時,可以利用這個特性來節省記憶體使用量。

例如:decorator() 這個 function 要對一個大型陣列的資料做處理:

function decorator($data)
{
    $sum = 0;
    foreach ($data as $item) {
        $sum += $item;
    }
    $data['average'] = $sum / count($data);
    $data['sum'] = $sum;

    return $data;
}

上面的 function 因為會修改 $data 的內容,所以 PHP 會 clone 一個 $data 再來做修改。

改成以下的寫法:

function decorator($data)
{
    $sum = 0;
    foreach ($data as $item) {
        $sum += $item;
    }

    $change = [
        'average' => $sum / count($data),
        'sum' => $sum,
    ];

    return $change;
}

foreach (decorator() as $key => $val) {
    $data[$key] = $val;
}

在 decorator() 並不會動到 $data 的內容,所以不需要 clone $data,而是在 function 執行結束以後,直接對 $data 做修改。這樣只需要多儲存 $change 陣列,和後續的處理動作,而不會讓使記憶體用量 double。

Tags:PHP

WD 高雄服務中心地點更換

Posted on 2016 年 10 月 20 日2021 年 3 月 12 日 By 日落 在〈WD 高雄服務中心地點更換〉中有 1 則留言

之前 WD 的特約服務中心是在 SET 復得科技那邊,但今天要送修硬碟時才發現 SET 已不再代為服務,地點改到雷德硬碟資料救援那邊去。

走路看到廣告招牌才知道這件事情,然而 WD 官方網站則完全找不到任何訊息,實在很不爽。

so … 2016/07/01 以後,WD 的服務中心改至雷德硬碟資料救援

地址:高雄市三民區建國二路152號
營業時間:請參考公司網站說明

Tags:生活雜記

Synology 的套件庫及管理工具 ipkg

Posted on 2016 年 10 月 20 日2021 年 3 月 12 日 By 日落 在〈Synology 的套件庫及管理工具 ipkg〉中尚無留言

一直以為 Synology 的 DSM 上面,只有預設的套件管理工具和社群套件可以安裝使用,但這實在不夠力。

昨天因為 S.M.A.R.T. 檢測失敗 (但也沒寫問題在哪裡),所以只好找 badblocks 來手動測試。badblocks 一次市要跑數個小時的,若因為網路不穩斷線會導致 process 被中斷,只能重跑,至少要裝個 session / screen manager 來支援 (我習慣用 GNU screen)。

後來搜尋後找到 ipkg 這項套件管理工具,安裝完畢以後可以用類似 ubuntu aptitude 的操作方式來安裝套件。

常用工具都已經有包好可以直接下載使用,像是 htop、screen 等等,可以透過 ipkg search / install 來使用。binary 預設放在 /opt/bin 底下,再調整一下 PATH 即可直接呼叫。

Ref:

  • https://forum.synology.com/enu/viewtopic.php?t=94291
  • http://www.vspecialist.co.uk/2014/09/how-to-install-ipkg-on-a-synology-nas/
  • http://blog.fat-nerds.com/dot-nerd/install-ipkg-on-synology-in-chines/
Tags:資訊學習

增加 MySQL insert 速度的撇步

Posted on 2016 年 10 月 15 日2021 年 3 月 12 日 By 日落 在〈增加 MySQL insert 速度的撇步〉中尚無留言

一次要新增大批資料到 MySQL 時,就會 MySQL 吃 CPU 又卡 I/O wait,這個時候如果沒時間吃下午茶的話實在會有點不爽 (?)

假設今天有個 table 長這個樣子:

mysql> desc users;
+--------------+---------------------+------+-----+---------+-------+
| Field        | Type                | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+-------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    |       |
| email        | varchar(200)        | YES  |     | NULL    |       |
| display_name | varchar(500)        | YES  |     | NULL    |       |
| reg_date     | int(10) unsigned    | YES  |     | NULL    |       |
| last_login   | int(10) unsigned    | YES  |     | NULL    |       |
| delete_at    | int(10) unsigned    | YES  |     | NULL    |       |
+--------------+---------------------+------+-----+---------+-------+

登入、使用者管理等動作,我們會為以下幾個欄位加上 index 以加快查詢速度:

  • email
  • reg_date
  • last_login
  • delete_at

這個時候我們新增一筆資料時,MySQL 大概會做幾個動作:

  1. 新增一個 row
  2. 更新 index
    1. 更新 email index
    2. 更新 reg_date index
    3. 更新 last_login index
    4. 更新 delete_at index

所以如果只是把新增一筆資料,事情最多的不是建立一個 record,而是更新所有的 index。假設要新增的資料有 10000 筆,新增資料的 I/O 就當作 10000 次好了,更新 index 就另外再增加 40000 次 I/O。

若這 10000 筆資料是一次處理完,且不打算中斷,是否有發法可以減少 index 處理的次數?答案是 transaction。

當 10000 個 insertion 放在同一個 transaction 時,MySQL 會在 insertion 確認成功以後再來一次 update index。也就是說原本 update index 跑 40000 次,現在只需要跑 4 次。

由於 transaction 會造成 lock,新增資料前可以先試試看一個 transaction 要新增幾個 record,lock 的時間才不會影響到其他服務的運作。

ref:

  • MySQL :: MySQL 5.5 Reference Manual :: 8.2.2.1 Speed of INSERT Statements
Tags:MySQL

塔塔加 10 分鐘遊

Posted on 2016 年 10 月 10 日2021 年 3 月 12 日 By 日落 在〈塔塔加 10 分鐘遊〉中尚無留言
塔塔加 10 分鐘遊

本來打算連假走塔塔加抒發一下最近累積的壓力,不過天公不做美,連續下了幾天的雨,到了塔塔加遊客中心以後就決定往回走了。

由於下午的關係,阿里山到塔塔加的路並不好走,中途有部份地段有落石,也有路基不穩的狀況,建議上山之前還是要注意一下道路狀況。

塔塔加遊客中心,除了有賣紀念品以外,也有阿里山生態的教育影片,二樓則有餐廳。餐廳主要是以桌菜為主,雖然有單點但價位都不低,倒是 200 元的單人套餐份量和品質都很棒。

塔塔加遊客中心 200 元的單人套餐

Tags:旅遊, 生活雜記

文章分頁

上一頁 1 ... 107 108 109 ... 322 下一頁

其他

關於我  (About me)

  文章 RSS Feed

  留言 RSS Feed

Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Raspberry Pi Ubuntu Unix Vim Web Windows XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.