标题:提高代码的运行速度
只看楼主
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
结帖率:86.67%
已结贴  问题点数:100 回复次数:37 
提高代码的运行速度
电脑配置

VFP9 汉化版 7423
这是一门科目的考试成绩,保存在JMSS1字段中,共有8题(各有129403条记录),以逗号分隔,成绩不但有0分、3分,还有带小数位的成绩(如1.5分),见下图

2,2,2,2,0,3,3,3 分别代表每题得到的分数。
根据这台电脑的配置情况,获取这门科目8题的有关数据耗时4秒。
要求:1、获取每题分值对应的人数,效果图如下

      2、尽最大能力缩短程序运行的时间

附上运行代码及相关数据:
sp.rar (451.53 KB)

程序代码:
t1 = SECONDS()
CLOSE DATABASES 
USE 选择\sp ALIAS aa
ln = OCCURS(",", jmss1) + 1 && 获取题目的数量
FOR lnj = 1 TO ln
    CREATE CURSOR fz (nfz n(4, 2), nsl I) && 保存分值的
    INDEX on nfz TAG fz
    SELECT VAL(GETWORDNUM(jmss1, lnj, ",")) nfz FROM aa INTO CURSOR temp
    SCAN 
        IF SEEK(temp.nfz, "fz", "fz") = .T.
            REPLACE nsl WITH nsl + 1 IN fz
        ELSE
            INSERT INTO fz VALUES (temp.nfz, 1)
        ENDIF
    ENDSCAN
ENDFOR 
MESSAGEBOX(SECONDS() - t1)
SELECT fz
BROWSE 


收到的鲜花
  • schtg2021-04-03 05:49 送鲜花  2朵  
搜索更多相关主题的帖子: 运行 速度 代码 temp 获取 
2021-03-31 20:44
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
如果不用临时表,用字符,时间可以缩短为3.3秒,于事无补。

坚守VFP最后的阵地
2021-04-01 07:58
radiofan
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:11
帖 子:466
专家分:696
注 册:2006-7-30
得分:0 
有空试试
2021-04-01 08:54
gs2536785678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:45
帖 子:565
专家分:1668
注 册:2017-7-16
得分:0 
能够写出代码解决问题已经不容易了,千万不用求全自责。
说真的,程序员的工作只是使得程序顺利运行,没有时间去优化代码。
2021-04-01 10:29
瓜瓜1990
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:18
帖 子:125
专家分:699
注 册:2020-2-25
得分:10 
直接用group by不一样么,快不少
程序代码:
t1 = SECONDS()
CLOSE DATABASES 
USE sp ALIAS aa
ln = OCCURS(",", jmss1) + 1 && 获取题目的数量
FOR lnj = 1 TO ln
    temp="temp"+"_"+TRANSFORM(m.lnj)
    SELECT VAL(getwordnum(jmss1,m.lnj,",") )nfz ,COUNT(*) as nrs FROM aa INTO CURSOR (temp) GROUP BY 1
ENDFOR 
MESSAGEBOX(SECONDS() - t1)
BROWSE 


piu~piu~
2021-04-01 10:41
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
1 楼代码变更如下
程序代码:
T1 = SECONDS()
CLOSE DATABASES 
USE 选择\sp ALIAS aa
ln = OCCURS(",", jmss1) + 1 && 获取题目的数量
FOR lnj = 1 TO ln
    CREATE CURSOR fz (nfz n(4, 2), nsl I) && 保存分值的
    INDEX on nfz TAG fz
    SELECT aa
    SCAN 
        IF SEEK(VAL(GETWORDNUM(aa.jmss1, lnj, ",")), "fz", "fz") = .T.
            REPLACE nsl WITH nsl + 1 IN fz
        ELSE
            INSERT INTO fz VALUES (VAL(GETWORDNUM(aa.jmss1, lnj, ",")), 1)
        ENDIF
    ENDSCAN
ENDFOR 
MESSAGEBOX(SECONDS() - T1)

发本帖的原意是,在不使用SQL命令查询的前提下,VFP命令得到结果的极限运行时间。
SUBSTR()与GETWORDNUM()在截取字符串时各有优势,如果字符串中子字符串的宽度是一样的(以分隔符分隔的10000个子字符串),GETWORDNUM()截取子字符串所需时间是SUBSTR()截取子字符串所需时间的60倍(至少);如果字符串中子字符串的宽度是不一样的(如本题中分值带有小数位),GETWORDNUM()的优势就明显了。
如:
2,2,2,2,0,1.5,3,3
2,2,2,2,0,3,1.5,3
2,2,2,2,0,3,3,1.5
因为你不知道带小数位的分值出现在那一题中,所以用SUBSTR()截取子字符串很麻烦。

[此贴子已经被作者于2021-4-1 11:17编辑过]


坚守VFP最后的阵地
2021-04-01 11:06
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
以下是引用瓜瓜1990在2021-4-1 10:41:26的发言:

直接用group by不一样么,快不少
t1 = SECONDS()
CLOSE DATABASES
USE sp ALIAS aa
ln = OCCURS(",", jmss1) + 1 && 获取题目的数量
FOR lnj = 1 TO ln
    temp="temp"+"_"+TRANSFORM(m.lnj)
    SELECT VAL(getwordnum(jmss1,m.lnj,",") )nfz ,COUNT(*) as nrs FROM aa INTO CURSOR (temp) GROUP BY 1
ENDFOR
MESSAGEBOX(SECONDS() - t1)
BROWSE

谢谢瓜瓜1990

坚守VFP最后的阵地
2021-04-01 11:09
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:5 
数据量不够大,效果不明显的,才10W的数据,要100W去,估计很明显;因为各人的电脑配置不相同
2021-04-01 11:49
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
以下是引用mywisdom88在2021-4-1 11:49:08的发言:

数据量不够大,效果不明显的,才10W的数据,要100W去,估计很明显;因为各人的电脑配置不相同

代码运行时间以我的电脑为准

坚守VFP最后的阵地
2021-04-01 12:06
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 

我的晕死,190秒
2021-04-01 12:58



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-505310-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.144885 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved