[20230922]dc命令複雜學習3.txt
[20230922]dc命令複雜學習3.txt
1.問題提出:
--//前一段時間簡單學習了dc,累加的例子:
$ cat a.txt
1111
2222
3333
4444
$ cat a.txt | dc -f - -e "[+z1<r]srz1<rp"
11110
$ dc -f a.txt -e "[+z1<r]srz1<rp"
11110
--//實際上如果累加資料量很大,這樣的執行效率很低的,因為每次都要判斷堆疊是否還有資料(z命令,佇列越長執行效率越低)
--//實際上開始我就想,如果根據開始插入堆疊的數量生成對應的數量的字元'+' ( 注:生成+的數量等於插入堆疊的數量-1),
--//那不是更加簡單呢? 自己再做一些嘗試:
2.嘗試實現:
$ dc -f a.txt -e "zp"
4
$ (cat a.txt ; seq 2 $(dc -f a.txt -e "zp"| tr -d '\r') | xargs -IQ echo + ; echo pq ) | dc -f -
11110
--//注:我的測試在cygwin下,dc -f a.txt -e "zp"的輸出結果多了1個\r字元,必須刪除它。
--//我上面的例子使用seq 生成對應+,如何全部使用dc實現呢?
--//先做z操作插入堆疊的數量,然後產生對應數量的+就可以了.改寫如下:
$ cat a.txt | dc -f - -e "z [+ la 1 - sa la 1<r ]sr sa la 1<r pq"
11110
$ dc -f a.txt -e "z [+ la 1 - sa la 1<r ]sr sa la 1<r pq"
11110
--//簡單解析,不作記錄我估計以後自己都看不懂程式碼表示怎麼:
--//z 插入當前堆疊的數量到堆疊頂部,在該例子是4.
--//[+ la 1 - sa la 1<r ]sr 將[]括號的內容儲存到暫存器r.以後迴圈執行裡面的內容,同時出堆疊.
--//sa 儲存堆疊頂部的值到暫存器a,同時出堆疊.這裡暫存器a儲存的值開始是4.
--//la 把暫存器a的內容放入堆疊,這裡暫存器a=4的值放入堆疊.
--//1<r 插入1到堆疊 做比較如果1 < 4 ,呼叫暫存器r的內容執行.形成遞規.注意執行<時,堆疊頂部的比較的2個值同時出堆疊.
--//單獨解析: [+ la 1 - sa la 1<r ]
--// + 對當前堆疊頂部的2個數值做一次加法運算.
--// la 把暫存器a的內容放入堆疊.
--// 1 - 把1放入堆疊.並且與前面放入暫存器a的內容放入堆疊的值做減法運算.也就是做迴圈.
--// sa 儲存堆疊頂部的值到暫存器a,同時出堆疊.
--// la 把暫存器a的內容放入堆疊
--// 1<r 插入1到堆疊 做比較如果1 < 暫存器a的值 ,呼叫暫存器r的內容執行.形成遞規.注意執行<時,堆疊頂部的比較的2個值同時出堆疊.
--//加入一個顯示整個堆疊的命令f就很清楚了.
$ dc -f a.txt -e "z [ + la 1 - sa la 1 f 61P 61P 61P 61P 10P <r ]sr sa la 1 f 61P 61P 61P 61P 10P <r pq"
1
4
4444
3333
2222
1111
====
1
3
7777
2222
1111
====
1
2
9999
1111
====
1
1
11110
====
11110
--//如果演演算法改一下,要輸出對應數量的字元+,該如何操作呢?
--//+的ascii碼=43 ,注:在vim下在移動到+字元下按ga,在vim的提示行顯示對應ascii碼值(10,16,8進位制). 空格的ascii=32,換行的
--//ascii=10.
$ cat a.txt | dc -f - -e "z [43P la 1 - sa la 1<r ]sr sa la 1<r "
+++
--//注意我的以上測試並沒有改變dc插入堆疊的值.你最後加入f顯示整個堆疊.
$ cat a.txt | dc -f - -e "z [43P la 1 - sa la 1<r ]sr sa la 1<r 10P f"
+++
4444
3333
2222
1111
--//使用空格分開呢?
$ dc -f a.txt -e "z [43P 32P la 1 - sa la 1<r ]sr sa la 1<r "
+ + +
--//這樣也可以寫成如下:
$ (cat a.txt ; dc -f a.txt -e "z [43P 32P la 1 - sa la 1<r ]sr sa la 1<r 10P"; echo pq ) | dc -f -
11110
3.測試執行效率:
--//測試這樣改進的執行效率如何?家裡沒有linux的環境,使用cygwin 在windows下測試:
--//cygwin的執行效率並不是很高.
$ seq 100000 > b.txt
$ time dc -f b.txt -e "[+z1<r]srz1<rp"
5000050000
real 0m10.630s
user 0m0.000s
sys 0m0.015s
$ time dc -f b.txt -e "z [+ la 1 - sa la 1<r ]sr sa la 1<r pq"
5000050000
real 0m0.648s
user 0m0.000s
sys 0m0.015s
--//明顯快了一大截。測試使用bc看看
$ paste -sd+ b.txt | bc -l
(standard_in) 1: Function too big.
--//拚接為1行時太長了,實際上操作bc 1行接受的行長度存在限制,看下面的測試.
$ time ((sed -e 's/^/s+=/g' b.txt ; echo s ) | bc -l)
5000050000
real 0m0.658s
user 0m0.061s
sys 0m0.045s
--//兩者相差不大。
--//順便測試一行最大容納多少字元。
$ head -2499 b.txt | paste -sd+ | bc -l
3123750
$ head -2500 b.txt | paste -sd+ | bc -l
(standard_in) 1: Function too big.
$ head -2500 b.txt | paste -sd+ | wc
1 1 11393
$ head -2499 b.txt | paste -sd+ | wc
1 1 11388
--//我估計是超出bc一行能輸入的字元數量的限制。因為head -2500 b.txt | paste -sd+可以正常執行。
$ time (head -2499 b.txt | paste -sd+ | bc -l)
3123750
real 0m0.535s
user 0m0.015s
sys 0m0.030s
$ time (head -2499 b.txt | dc -f - -e "z [+ la 1 - sa la 1<r ]sr sa la 1<r pq")
3123750
real 0m0.355s
user 0m0.000s
sys 0m0.046s
--//還是dc略勝一籌。我估計是因為bc的執行過程中使用paste拼接的原因。
$ head -2499 b.txt | paste -sd+ > c.txt
$ echo quit >> c.txt
$ time bc -l c.txt
3123750
real 0m0.146s
user 0m0.000s
sys 0m0.000s
$ head -2499 b.txt > c.txt
$ (dc -f c.txt -e "z [43P la 1 - sa la 1<r ]sr sa la 1<r "; echo pq ) >> c.txt
$ time dc -f c.txt
3123750
real 0m0.192s
user 0m0.000s
sys 0m0.031s
--//在寫好計算公式的情況下,兩者差不多,bc也許更快一些。
4.補充說明:
--//測試看看dc 以及bc 一行能接受字元的限制的具體數值.
$ head -2499 b.txt | paste -sd+ > c.txt
$ time bc -l c.txt
3123750
quit
real 0m2.148s
user 0m0.000s
sys 0m0.000s
--//嘗試修改c.txt 增加檔案第一行字元數量.僅僅增加1個字元就出現如下錯誤。
$ time bc -l c.txt
quit
c.txt 2: Function too big.
real 0m2.140s
user 0m0.015s
sys 0m0.000s
$ wc c.txt
1 1 11389 c.txt
$ ls -l c.txt
-rw-r--r-- 1 Administrator None 11389 2023-09-23 20:29:27 c.txt
--//檔案是linux格式,刪除最後1個字元0x0a以及插入的字元,bc的一行輸入快取是11387字元。
--//多次嘗試我發現實際上情況比我前面的測試要複雜:
$ head -5 e.txt
1
1
1
1
1
--//建立一個全部是數字1的檔案。
$ wc e.txt
40000 40000 80000 e.txt
--//共40000行。
$ paste -sd+ e.txt | bc -l
(standard_in) 1: Function too big.
$ head -8192 e.txt | paste -sd+ |bc -l
8192
$ head -8193 e.txt | paste -sd+ |bc -l
(standard_in) 2: Function too big.
$ head -8194 e.txt | paste -sd+ | wc
1 1 16388
--//放棄探究,有點離題了。
--//測試dc的情況:
$ head -2499 b.txt | paste -sd' ' > d.txt
$ ls -l d.txt
-rw-r--r-- 1 Administrator None 11388 2023-09-23 20:32:51 d.txt
$ (dc -f d.txt -e "z [43P la 1 - sa la 1<r ]sr sa la 1<r "; echo pq ) >> d.txt
$ time dc -f d.txt
3123750
real 0m0.181s
user 0m0.000s
sys 0m0.015s
--//增加1個字元看看,修改最後的2499 為 24991。
$ time dc -f d.txt
3146242
real 0m0.214s
user 0m0.000s
sys 0m0.015s
--//3123750 - 2499 +24991 = 3146242 , 結果正確。
$ paste -sd' ' b.txt > d.txt
$ (dc -f d.txt -e "z [43P la 1 - sa la 1<r ]sr sa la 1<r "; echo pq ) >> d.txt
$ time dc -f d.txt
5000050000
real 0m0.461s
user 0m0.000s
sys 0m0.015s
$ ls -l d.txt
-rw-r--r-- 1 Administrator None 688897 2023-09-23 20:41:58 d.txt
$ cat d.txt | dc -f -
5000050000
--//dc沒有這個限制,甚至bash shell命令列的限制。
--//bash shell命令列的限制我記憶裡各個版本不一致,好像最大可以達到128K,有一些甚至2621440。我不測試了。
$ getconf -a | grep -i arg
_POSIX_ARG_MAX 4096
NL_ARGMAX 9
ARG_MAX 32000
$ getconf ARG_MAX
32000
--//我的cygwin測試環境32000.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2987245/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL學習(三) 複雜查詢SQL
- 命令列寫複雜語句命令列
- 如何快速學習複雜事物的指南 - BaldauLDA
- 如何建立複雜的機器學習專案?機器學習
- linux中查詢find命令的複雜用法Linux
- DDD之理解複雜度、尊重複雜度、掌控複雜度複雜度
- 資料結構與演算法學習-複雜度分析資料結構演算法複雜度
- 資料結構基礎學習之時間複雜度分析資料結構時間複雜度
- Vulnhub DC-1靶場學習筆記筆記
- 準確率達 95%,機器學習預測複雜新材料合成機器學習
- 時間複雜度跟空間複雜度時間複雜度
- 複雜性Complex與複雜Complicated區別 - Sonja
- 時間複雜度與空間複雜度時間複雜度
- 時間複雜度和空間複雜度時間複雜度
- mysql學習方法雜談MySql
- 學會用 Go 解析複雜 JSON 的思路GoJSON
- Linux 命令學習Linux
- ip命令學習
- 複雜度分析複雜度
- 時間複雜度O(n)和空間複雜度時間複雜度
- 複雜度分析的套路及常見的複雜度複雜度
- C#學習筆記--複雜資料型別、函式和結構體C#筆記資料型別函式結構體
- 《資料結構與演算法之美》學習筆記之複雜度資料結構演算法筆記複雜度
- Kubernetes 複雜嗎?可以不復雜
- Android 學習筆記雜記Android筆記
- [學習筆記 #5] 雜湊筆記
- 小前端學演算法之複雜度分析前端演算法複雜度
- 如何開始複雜性科學的研究? - systemsinnovation
- 學習一個 Linux 命令:shutdown 命令Linux
- 複雜連結串列的複製
- 淺析程式碼圈複雜度及認知複雜度複雜度
- Shell學習【test命令】
- virsh命令學習(一)
- dos命令的學習
- CSS學習-Flex佈局複習CSSFlex
- JavaScript 複習之例項物件與 new 命令JavaScript物件
- 複雜控制語句
- SQL 複雜查詢SQL