Linux的cpu/power自動省電工具

剛好在Hacker News 上看到,記錄一下,也許以後會用得到。

有人分享了一個開源的cpu/電源自動化管理工具(auto-cpufreg),讓Linux的筆電的cpu可以電池模式下降件cpu的負載,而在插電模式下,又可以自動的提高cpu的運算能力。

如果有人有Linux的筆電,剛好也可以試試。

Reference:

Python concurrency的進展

在 Hacker News 上看到的資訊,目前有一位開發者最近實作出PoC版本的CPython multi-threading。

而會這麼說,主要是因為目前的Python在multi-thread方面的發展,還是受限於GIL(global interpreter lock)的影響,所以實際上在執行時,只會有一個thread 在運作。

而會有這樣的設計,也是跟GC(Garbage Collection)有比較大的關係,因為Python的GC是採用reference count的原理,當一個物件不再被任何其它物件所使用時,它就會是可以被回收的。而回收的方式就是透過GIL。

To avoid such problems, the GIL only allows one thread to be running in the interpreter (i.e. to actually be running Python code) at a time; that takes away almost all of the advantage of using threads in any sort of compute-intensive code.

A viable solution for Python concurrency [LWN.net]

不過目前這個設計有機會被改進了,即是社群開發者提供的那個 PoC版本CPython,而主要的改進方向是透過改進GC演算法,更詳細的作法可以直接參考這裡

相信這功能如果可以進到CPython之後的版本的話,這一定會大幅強化Python的優勢的,等之後看後續的發展了XD

Reference:

AWS Lambda的”冷啟動”時間

在Hacker News 上看到的一些相關比較,作者比較了現有AWS Lambda 的程式語言,並記錄每種語言在不同情境下的cold start的時間。

測試架構大概如下:

clients -> HTTP API -> Lambda function -> Dynamo DB

直接跳到測試結果

Cold start:

* All languages(except Java and .Net) have a pretty small cold start.
* Java even cannot start with 128Mb. It needs more memory. But GraalVM can help in this case.
* Rust beats all runtimes for all setups for cold start, the only exception is 128 MB where Python is the best.

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

Warm start:

* Golang and Rust are the winners. They have the same brilliant performance.
* .Net has almost the same performance as Golang and Rust, but only after 1k iterations(after JIT).
* GraalVM has a stable great performance almost the same as .Net and a bit worse than Rust and Golang. But it doesn’t perform well for the smallest setup.
* Java is the next after GraalVM.The same as .Net, Java needs some time(1–3k iterations) for JIT(C1). Unfortunately for this particular use case, I was not able to achieve the expected great performance after JIT C2 compilation. Maybe AWS just disabled it.
* Python has stable good performance but works too slow for the 128 MB.
* Ruby has almost the same performance as Python, but we see some duration growing after 20 min invocations(after 15k iteration).
* NodeJs is the slowest runtime, after some time it becomes better(JIT?) but still is not good enough. In addition, we see the NodeJS has the worst maximum duration.

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

Go與Rust是其中最穩定的且效能最好的,在幾乎所有的情境下,都是前2名。(唯一的例外是,Python在128MB RAM 的環境下是最快的)。

對我而言比較意外的是Node.js,沒想到會是最慢的!?

Reference:

AWS Lambda battle 2021: performance comparison for all languages (cold and warm start) | by Aleksandr Filichkin | Sep, 2021 | Medium

常用指令 – awk

awk 是個很強大的工具, 透過其特製的語法可以在很多變化上處理pipe或檔案內容;之前一段時間不碰後,又忘了之前使用過awk語法,趁最近又開始接觸來重新複習這個工具。

測試用檔案 – log.txt

假設一個log檔的檔名為log.txt,且內容如下:

2 this is a test 
3 Are you like awk 
This's a test
10 There are orange,apple,mongo

基本搭配print做格式化輸出

NOTE:

  • 值得注意的是,$0awk中代表的是整行文字
# 在print使用逗號,可以在輸出時用空白隔開$1與$4
awk '{print $1,$4}' log.txt

(上述指令針對每一行的log,截取第1個與第4個讀取到的文字)

2 a
3 like
This's
10 orange,apple,mongo

透過-F 更改分割字元

由於預設awk是使用空白當分割字元來處理同一行文字的,若要改變分割字元,則可以使用-F 這個flag。

aws -F , '{print $1,$2}' log.txt

(上述指令針對每一行的log,透過,分隔以後,截取分割後的第1個與第2個讀取到的文字)

2 a
3 like
This's
10 orange apple

(以這個log檔來看,只有最後一行才會被分割成多個arguments)

透過-v 來代入自訂的變數

透過預先定義好的變數

awk -v a=1 -v b=2 '{print $1,$1+a,b}' log.txt

(上述指令定義了a, b 2個變數與值,且在print時使用它們)

2 3 2
3 4 2
This's 1 2
10 11 2

透過運算符號來使用awk

支援的運算符號可以參考這裡

對每一行文字,過濾只有第一個參數大於2
awk '$1>2' log.txt

# output
3 Are you like awk
This's a test
10 There are orange,apple,mongo
對每一行文字,過濾只有第一個參數大於2,且第二個參數必須是"Are"
awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt

# output
3 Are you
對每一行文字,列出只有字元數大於20的行
awk 'length>20 {print $0}' log.txt

# output
10 There are orange,apple,mongo

搭配Regular expression使用

awk中,可以透過運算符號~!~來去搭配正規表示法使用。

對於每一行文字,當第一組參數不是數字時才會被print出來
awk '$1 !~ /[0-9]/ {print $0}' log.txt

# output
This's a test

對於每一行文字,只有當第一組參數是數字時才會被print
awk '$1 ~ /[0-9]/ {print $0}' log.txt

# output
2 this is a test
3 Are you like awk
10 There are orange,apple,mongo

對於每一行文字,只有符合正規表示法時才會被print

如果只是要對整行文字作匹配的話,則可以直接用這方式

awk '/re/ ' log.txt

#output
3 Are you like awk
10 There are orange,apple,mongo

或加個!來過濾掉匹配到的每一行文字

awk '!/re/ ' log.txt

#output
2 this is a test
This's a test

搭配awk的進階使用

awk常見可以使用的keyword可以參考這裡

過濾掉第一行的文字(通常可用於csv檔拿掉header)
awk 'NR != 1' log.txt

# output
3 Are you like awk
This's a test
10 There are orange,apple,mongo

(我猜NR指的應該是Nnumb of Row)

對文字檔的特定參數做數字加總,並且print出來
awk '{sum+=$1} END {print sum}' log.txt

# output
15

(如果每一行的第一個參數是數字的話,就會對它做加總並暫存在sum這個變數上)

針對文字檔中的每一行,來做分組與處理

假設我們有個文字檔如下,然後我們想要針對每個Category的值串起來在印出來

Category: OS
Windows
Liux
Unix
Category: CPU
x86
arm64
amd64
Category: RAM
1GB
2GB
4GB
8GB
16GB

awk '/Category/ {header=$0; if (v) print v; v=""; next} { v=(!v) ? header"="$0 : v","$0;} END {print v;}' support_sepcs.txt

# output
Category: OS=Windows,Liux,Unix
Category: CPU=x86,arm64,amd64
Category: RAM=1GB,2GB,4GB,8GB,16GB

這個指令用了到幾個進階的功能:

  • /Category/ 用來匹配當遇到Category那一行的文字時,會在{header=$0 ...;next}中處理。(結尾的next是指說跳過後面的{v=(!v)…}相關的工作)
  • () ? : 用三元運算符號來去給v這個變數值。
  • END 用來處理最後的收尾。
  • 整個指令的邏輯是,當如果遇到文字中含Category時,則那行的文字會當作是接下去的header,然後如果v 目前是有值的情況下,則print v
    (這個情況v會是前面的字串組成的結果, 例如處理Category: CPU時,v這時會有值,且值會是Category: OS=Windows,Liux,Unix)。
    若沒遇到Category的話,則繼續append 目前的這一行文字到v這個變數上。
    最後一個Category: RAM則是透過 END { print v}來去print出來。
  • 如果在header後想要多處理else的話,會是這樣的語法:
    {header=$0; {if (v) { print v; v=""; next } else {v="";next}}

總結

整個awk的進階使用還更複雜,尤其是它支援許多語法,透過它的語法可以寫成另一個awk的script了,然後在指令中讀取來使用,像是awk -f cal.awk log.txt

reference

常用指令 – xargs

基本上常搭配其它linux指令 (find, awk, sed, grep…)一起使用,主要是因為一些linux的指令是沒直接支援pipe,所以可以透過xargs將前面pipe的輸出當成input arguments 給下一個指令使用;

xargs 後面沒有接任何的指令時,預設是以 echo 來進行輸出喔

將find的結果,透過xargs 來當作grep 主要要找的對象

find . -name "*.go" -print | xargs grep "src"

-0 flag

-0 flag主要是用來讓xargs 來讓可以去處理需要escape的字元,像是空白字元…

-n flag

-n flag 是用來指定每隔多少個要切割成一個pipe的arguments,也就是目前的pipe經過xargs以後會產生N/n 個pipe(N為目前pipe的argument數量)。如果沒有設定的話預設為把所有xargs 當下截取到的內容全部收集到目前這個pipe中。

舉例來說,一個env檔的內容如下:

FOO=123
BAR=456
LOCAL=127.0.0.1
PORT=3000

如果我們沒加-nflag時,用下面的指令:

cat env| xargs

則輸出結果會是 (env檔中的4個環境變數會被當成目前這個pipe的argument)

FOO=123 BAR=456 LOCAL=127.0.0.1 PORT=3000

但如果指令改成是下面這樣時

cat env| xargs -n 2

則輸出結果會是 (env檔的4個環境變數被切割成每2個是一組argument, 並且丟到下一個pipe中,所以這樣就fanout成2個pipe了)

FOO=123 BAR=456
LOCAL=127.0.0.1 PORT=3000

-I flag

-I 主要是可以用來將截取到的內容,暫存成一個變數名稱,來方便下個指令使用。

以下面的例子來說,會將所有找到的 *.conf檔案,透過xargs暫存到變數{}中,所以接下來的ls -al {}就可以這樣用…

find /etc/ -name "*.conf" | xargs -I{} ls -al {}

另個例子則是像是備份所有的.conf檔,則可以透過-I flag

find /etc/ -name "*.conf" | xargs -I{} cp {} {}.bk

integrate with bash

更彈性的用法是,它可以直接當作bash的輸入arguments;若一樣以前面的env 檔來當例子,透過以下指令我們可以透過一個簡短的bash來處理其中的第3個($2)環境變數。

cat env| xargs bash -c 'export $2'

Reference:

一本介紹給開發者用的數學書

很早之前從Hacker Daily News上看到的相關討論,主要是有人推薦了一本可以給開發者看的數學書,目標族群是沒有受過正規學校教育的開發者,或著是像我這種已經把大多數學的東西環給學校的開發者XD

As the title implies, the book is targeted towards programmers who do not have an academic math background. 

A Programmer’s Introduction to Mathematics – BIT-101

書的內容含蓋了下面的主題:

* Polynomials
* Sets
* Graphs
* Calculus with one variable
* Linear algebra
* Eigenvectors and Eigenvalues
* Multivariable calculus
* Groups

A Programmer’s Introduction to Mathematics – BIT-101

剛也稍微翻了一下,感覺書的重點是讓開發者可以較容易的去閱讀一些數學公式以外,並且用一些程式範例讓開發者理解一個數學公式其對應的程式碼大概會長怎麼樣。

感覺蠻值收著,以後可以當工具書參考用…

reference: