ITPub博客

首页 > Linux操作系统 > Linux操作系统 > [20191104]数值累加的各种方法3.txt

[20191104]数值累加的各种方法3.txt

原创 Linux操作系统 作者:lfree 时间:2019-11-04 10:26:35 0 删除 编辑

[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博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2662466/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969582