标题:如何提高程序运行速度
只看楼主
fdqzy
Rank: 1
等 级:新手上路
帖 子:354
专家分:0
注 册:2016-8-15
得分:0 
老师:
这种代码没学过,必须读懂,才能依样画葫芦仿照运用,不枉老师的一片心。
我的理解如下(有的是错误的,请指正):
程序代码:
USE b1
BLANK FIELDS s1_3,s4 all
GO TOP
DIMENSION a12[10,2]  &&定义二维数据变量,10-要统计的10行,2-列数(如果是3列就是a12[10,3])
COPY TO ARRAY a12 FIELDS a1,a2 NEXT 9  &&复制当前和下9条记录(这个理解可能是错误的)

SKIP  && 指针下移(是如何移到第10行的 ?,如果前面“GO TOP”改为"GO 2",这里就是下移到第11行?)
SCAN REST &&从第10行开始扫描
    p11 = a1
    a12[10,1] = a1
    a12[10,2] = a2
    tj = 1  &&为什么初始值斌“1”?
    FOR i=1 TO 9 &&从1行到9行统计
        IF a12[i,1]=p11 OR a12[i,2]=p11
            tj = tj + 1  &&如果 a12[i,1]、a12[i,2]都等于p11,这个成立否?
        ENDIF
    ENDFOR
    REPLACE s1_3 WITH IIF(tj<4, 'S1_3', ''), s4 WITH IIF(tj>3, 'S4', '')
    ADEL(a12,1) &&删除数组第1行元素
ENDSCAN
SELECT * FROM b1

这是按1-10,2-11,3-12....进行统计的
如果要固定前9行,再与10行及以后每1行组成10行统计(即前9行+第10行,前9行+第11行,前9行+第12行.....)
应如何修改代码?

麻烦了!

[此贴子已经被作者于2020-9-15 20:53编辑过]

2020-09-15 20:50
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
回复 41楼 fdqzy
理解没什么大问题
固定前9行和统计过程在39、40楼有提到
IF语句的判断表达式符合实际要求就OK
2020-09-15 23:31
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用fdqzy在2020-9-15 20:50:11的发言:

如果要固定前9行,再与10行及以后每1行组成10行统计(即前9行+第10行,前9行+第11行,前9行+第12行.....)
应如何修改代码?
麻烦了!

改小小,每次统计后不删除数组的第一行就可以固定前9行,每次取第10的数据就可以。
程序代码:
USE b1
BLANK FIELDS s1_3,s4 all
GO TOP
DIMENSION a12[10,2]  &&定义二维数据变量,10-要统计的10行,2-列数(如果是3列就是a12[10,3])
COPY TO ARRAY a12 FIELDS a1,a2 NEXT 9  &&复制从当前行起计共9条记录(此时是最上面的9条记录)
SKIP  && 指针下移(执行COPY后记录指针指向第9行,执行SKIP后移到第10行,如果前面“GO TOP”改为"GO 2",这里就是下移到第11行
SCAN REST &&从第10行开始扫描
    p11 = a1
    a12[10,1] = a1
    a12[10,2] = a2
    tj = 1  &&为什么初始值斌“1”? 因第10行(a12[10,1]=p11 OR a12[10,2]=p11)肯定为真,tj最小为1
    FOR i=1 TO 9 &&从1行到9行统计
        IF a12[i,1]=p11 OR a12[i,2]=p11
            tj = tj + 1  &&如果 a12[i,1]、a12[i,2]都等于p11,这个成立否? 肯定成立,因是OR运算,两者有一个成立就为真
        ENDIF
    ENDFOR
    REPLACE s1_3 WITH IIF(tj<4, 'S1_3', ''), s4 WITH IIF(tj>3, 'S4', '')
    **ADEL(a12,1) &&删除数组第1行元素,要固定前9行的就不用删除
ENDSCAN
SELECT * FROM b1
2020-09-15 23:55
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:484
专家分:1827
注 册:2018-3-13
得分:5 
先学好走,再考虑跑
3楼代码的主要问题,是对 replace 命令的作用范围不够了解
正如吹版在32楼指出的,带 for 子句的 replace 作用范围是 all,这在 vfp 的帮助里有明确的说明
因此,如果有 N 条记录,你的 for循环 + replace 要遍历整个表 N * N 次
(假设表没有任何索引,或者有但却无法被 vfp 的 rushmore 利用)

所以,你只要给 replace 加上范围子句,就可以简单的让运行时间得到根本性改变
例如第一条:REPLACE Next 1 _1dxx WITH '_1DXX' FOR '_'$k_1d AND '_'$_1d      && AND RECNO()=i

[此贴子已经被作者于2020-9-16 04:40编辑过]

2020-09-16 04:37
fdqzy
Rank: 1
等 级:新手上路
帖 子:354
专家分:0
注 册:2016-8-15
得分:0 
以下是引用csyx在2020-9-16 04:37:42的发言:

先学好走,再考虑跑
3楼代码的主要问题,是对 replace 命令的作用范围不够了解
正如吹版在32楼指出的,带 for 子句的 replace 作用范围是 all,这在 vfp 的帮助里有明确的说明
因此,如果有 N 条记录,你的 for循环 + replace 要遍历整个表 N * N 次
(假设表没有任何索引,或者有但却无法被 vfp 的 rushmore 利用)

所以,你只要给 replace 加上范围子句,就可以简单的让运行时间得到根本性改变
例如第一条:REPLACE Next 1 _1dxx WITH '_1DXX' FOR '_'$k_1d AND '_'$_1d      && AND RECNO()=i

说得对,学识太浅,在解决实际问题的同时去学习。
2020-09-16 08:56
fdqzy
Rank: 1
等 级:新手上路
帖 子:354
专家分:0
注 册:2016-8-15
得分:0 
再请教关于行统计的问题:
我的常规处理办法是
程序代码:
create cursor b1 (c1 N(3),c2 N(3),m c(3))
insert into b1 values (70,54,"")
insert into b1 values (58,54,"")
insert into b1 values (49,86,"")
insert into b1 values (66,86,"")
insert into b1 values (75,96,"")

FOR i=1 TO RECCOUNT()
GO i
kk=''
IF c1>=60
kk=kk+'1'
ENDIF
IF c1<60
kk=kk+'0'
ENDIF
IF c2>=60
kk=kk+'1'
ENDIF
IF c2<60
kk=kk+'0'
ENDIF
GO i
REPLACE m WITH ALLTRIM(kk) 
endfor


统计:
程序代码:
create cursor b1 (m1 c(2),m2 c(2),m3 c(2),m4 c(2),m5 c(2),p1 c(3),p2 c(3),p3 c(3))
insert into b1 values ("M1","","M3","M4","","","","")
insert into b1 values ("M1","","","M4","","","","")
insert into b1 values ("","M2","M3","M4","M5","","","")
insert into b1 values ("","","","M4","","","","")
insert into b1 values ("","","M3","M4","M5","","","")

FOR i=1 TO RECCOUNT()
GO i
kk=0
IF 'M'$m1
kk=kk+1
ENDIF
IF 'M'$m2
kk=kk+1
ENDIF
IF 'M'$m3
kk=kk+1
ENDIF
IF 'M'$m4
kk=kk+1
ENDIF
IF 'M'$m5
kk=kk+1
ENDIF
GO i
REPLACE p1 WITH 'P1' FOR kk=1 AND RECNO()=i
REPLACE p2 WITH 'P2' FOR kk=2 AND RECNO()=i
REPLACE p3 WITH 'P3' FOR kk>2 AND RECNO()=i

endfor

求简捷的处理方法!

[此贴子已经被作者于2020-9-16 14:36编辑过]

2020-09-16 14:34
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
create cursor b1 (m1 c(2),m2 c(2),m3 c(2),m4 c(2),m5 c(2),p1 c(3),p2 c(3),p3 c(3))
insert into b1 values ("M1","","M3","M4","","","","")
insert into b1 values ("M1","","","M4","","","","")
insert into b1 values ("","M2","M3","M4","M5","","","")
insert into b1 values ("","","","M4","","","","")
insert into b1 values ("","","M3","M4","M5","","","")
SCAN
    n1 = OCCURS("M", m1 + m2 + m3 + m4 + m5)
    n1 = IIF(n1 > 3, 3, n1)
    REPLACE ("P" + TRANSFORM(n1)) WITH "P" + TRANSFORM(n1)
ENDSCAN
BROWSE

坚守VFP最后的阵地
2020-09-16 15:09
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
create cursor b1 (c1 N(3),c2 N(3),m c(3))
insert into b1 values (70,54,"")
insert into b1 values (58,54,"")
insert into b1 values (49,86,"")
insert into b1 values (66,86,"")
insert into b1 values (75,96,"")
SCAN
    REPLACE m WITH IIF(c1 >= 60, "1", "0") + IIF(c2 >= 60, "1", "0")
ENDSCAN
BROWSE

坚守VFP最后的阵地
2020-09-16 15:15
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
我一直坚持先学后用,不是现学现用,原因大家可以自己去想像

坚守VFP最后的阵地
2020-09-16 15:18
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:0 
REPLACE ...... FOR 条件  是对全表进行操作,凡是加了 FOR 的命令,运行速度都将受到影响,也就是运行时间延长了。
我在上面的回复中避免使用 FOR 子句,从而使程序的运行速度加快了。
SCAN ENDSCAN命令对表中的记录逐条进行扫描,扫描结束后,问题也得到了解决。

[此贴子已经被作者于2020-9-16 15:47编辑过]


坚守VFP最后的阵地
2020-09-16 15:45



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




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

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