[20191104]數值累加的各種方法3.txt

lfree發表於2019-11-04

[20191104]數值累加的各種方法3.txt

--//前一陣子做了數值累加的測試,
--//連結如下:
http://blog.itpub.net/267265/viewspace-2660877/=>[20191021]數值累加的各種方法.txt
http://blog.itpub.net/267265/viewspace-2661719/=>[20191028]數值累加的各種方法2.txt

--//如果記錄很多是不可能拼接成1行來實現累計的,比如:
$ seq 1000000 | paste -sd+ | bc
(standard_in) 1: parse error

--//本次測試看看大量累加選擇何種方式最快!!

1.建立測試指令碼:
set pagesize 0
spool aa.txt
select AMOUNT_SOLD from sh.sales;
spool off

SCOTT@book> select sum(AMOUNT_SOLD),count(*) from sh.sales;
SUM(AMOUNT_SOLD)   COUNT(*)
---------------- ----------
      98205831.2     918843

--//適當編輯aa.txt文字,刪除開頭以及結尾的非數字資訊.
$ wc aa.txt
  918843   918843 11026116 aa.txt

$ paste -sd+ aa.txt | bc
98205831.21

$ paste -sd+ aa.txt | bc -l
98205831.21
--//奇怪什麼會有累計誤差呢?先不管這個問題.

$ awk '{sum+=$1} END {printf("%.10f\n",sum)}' aa.txt
98205831.2100249678

$ seq 100 | xargs -I {} cat aa.txt >> aaa.txt
$ wc aaa.txt
  91884300   91884300 1102611600 aaa.txt

--//資料量擴大100倍.

2.測試:
--//奇怪這樣也可以執行,為什麼seq 1000000 | paste -sd+ | bc有問題呢?
$ time paste -sd+ aaa.txt | bc -l
9820583121.00
real    0m56.056s
user    0m58.227s
sys     0m2.145s

$ time awk '{sum+=$1} END {printf("%.10f\n",sum)}' aaa.txt
9820583120.8551120758
real    0m43.603s
user    0m43.135s
sys     0m0.371s
--//awk在做累計計算是存在誤差!!

$ time cat aaa.txt |xargs | sed 's/ /+/g' | paste -sd+ | bc
9820583121.00
real    1m6.532s
user    2m25.466s
sys     0m26.889s

--//dc計算太慢,我估計那串 -e '[+z1<r]srz1<rp',是判斷是否棧內還有資料,每次判斷浪費許多時間.
$ time seq 100000 | dc -f - -e '[+z1<r]srz1<rp'
Segmentation fault
real    0m13.743s
user    0m13.786s
sys     0m0.036s
--//100000條就需要13秒.就是aa.txt文字918843條(增加9倍),時間也是很長的.也就是dc僅僅合適資料比較少的情況.
--//可以看出最快awk,但是累計計算存在誤差,不推薦使用.還是paste -sd+加bc模式比較好.
    
3.為什麼bc計算存在偏差呢?

$ cat a.sql
set head off pagesize 0 feedback off verify off  echo off
set term off
spool bb.txt
select AMOUNT_SOLD from sh.sales;
spool off
set term on

SCOTT@book> @ a.sql

$ wc bb.txt aa.txt
  918843   918843 11026116 bb.txt
  918843   918843 11026116 aa.txt
 1837686  1837686 22052232 total

$ diff aa.txt bb.txt

$ paste -sd+ bb.txt | bc -l
98205831.21

--//沒有問題啊.我在toad下測試,結果正常.
select sum(AMOUNT_SOLD),count(*) from sh.sales;

--//實際上問題在sqlplus顯示數字的處理方式上.在sqlplus下執行如下就很清楚了.
SCOTT@book> select 98205831.21 , 8205831.21  from dual ;
98205831.21 8205831.21
----------- ----------
 98205831.2 8205831.21

--//仔細看了以前的連結:http://blog.itpub.net/267265/viewspace-2284458/=>[20181207]sqlplus下顯示資料精度.txt
--//沒有想到自己還犯了一個嚴重錯誤.另外寫一篇文章說明這個問題.
--//可以看出bc計算是正確的,問題在與sqlplus下顯示資料問題.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2662466/,如需轉載,請註明出處,否則將追究法律責任。

相關文章