前往Shuct.Net首页

Shudepb PB反编译专家长时间以来,为业内同类软件事实上的唯一选择.细节,彰显专业.态度,决定品质.

关于PowerBuilder的搜索

优化你的PowerBuilder程序 — 编程爱好者 programfan.com ProgramFan.com 回到首页 设为首页 加入收藏 网站留言 人才招聘频道 编程爱好者BLOG 编程爱好者论坛 首页 | 论坛 | 博客 | 人才招聘 | 书评 | 文章 | 资讯 | 下载 | 源码 | 项目交易 | 兴趣小组 | 网友作品 | 资源共享 | 收藏夹 | ACM题库 | VBAPI查询 您所在的位置:编程爱好者网站 - 文档中心 - PowerBuilder文章 - 正文 我要投稿 文章搜索 PowerBuilder文章 全部分类 优化你的PowerBuilder程序 (加入日期:2001-6-1) 【保存文章至硬盘】【打印文章】【字体:大 中 小】 分享到: 一段程序,完成了所需要的功能固然重要,但是提高执行效率,提高代码的可重复利用性,提高程序的可读性也是很重要的。刚刚读了一个前辈的帖子,感觉受益菲浅,拿将出来与大家共享 优化你的PowerBuilder程序 一、处理 SQL 语句 1、缓冲 SQL 语句 在应用程序中,有时需要反复调用同一组 SQL语句,在这种情况下,可以通过在应用中为这些 SQL 建立缓冲区来提高执行性能。在缺省情况下,SQL 语句的缓冲区是关闭的,你可以通过如下语句打开它: SQLCACHE = n n 表示装入缓冲区的 SQL 语句数量(缺省为0)。 例如: dw_1.SetTransObject(sqlca) SQLCA.dbParm = "SQLCache = 0" dw_1.retrieve() 如果将上例的 "SQLCache = 0" 改为 "SQLCache = 25",此句的执行效率将提高五分之一左右。但应注意缓冲区的大小,否则也将影响程序执行的性能。 注:此方法对用 ODBC 和 ORACLE 连接的数据库非常有效。 2、捆绑变量 请看下例: SQLCA.DBPARM = "DISABLEBIND=1" INSERT INTO DA_DH VALUES("1","河南0") INSERT INTO DA_DH VALUES("2","河南1") INSERT INTO DA_DH VALUES("3","河南2") INSERT INTO DA_DH VALUES("4","河南3") INSERT INTO DA_DH VALUES("5","河南4") INSERT INTO DA_DH VALUES("6","河南5") 这里未使用捆绑变量,在插入是 PB 将重新处理每个带有新值的SQL语句。如果将上例改为: SQLCA.DBPARM = "DISABLEBIND=0" INSERT INTO DA_DH VALUES("1","河南0") INSERT INTO DA_DH VALUES("2","河南1") INSERT INTO DA_DH VALUES("3","河南2") INSERT INTO DA_DH VALUES("4","河南3") INSERT INTO DA_DH VALUES("5","河南4") INSERT INTO DA_DH VALUES("6","河南5") 则系统将把 INSERT 语句按如下格式进行处理: INSERT INTO DA_DH VALUES(?,?) 其中 "?" 称为占位符。系统性能将有所增强。 3、用数据窗口代替 SQL 语句 通常,为了获得某些数据,采用数据窗口和 SQL 语句都是可行的,但是PB 对数据窗口和 SQL 语句采用不同的处理机制,因此,具有不同的效率。 例:为里检索电话档案中的用户名,可以利用 SQL 语句,将所有的数据检索到一个多行编辑中,也可以检索到一个数据窗口中。如果使用第一中方法:首先定义一个游标: DECLARE CUR CURSOR FOR SELECT "DA_DH"."HM" FROM "DA_DH"; 然后可以: STRING stxt[],st int li open cur do li = li + 1 fetch cur into :stxt[li] ; st=st+stxt[li] + "~r~n" loop while stxt[li]<>"" close cur; mle_1.txt = st 也可以使用第二种方法: dw_1.settransobject(sqlca) dw_1.retrieve() 利用 PowerBuilder PROFILER 工具进行检查,对比两种方法所需时间如下 方法 所需时间 (百分之一秒) SQL 语句     100.9857 数据窗口 49.0133   由于数据窗口或 DATASTORE 使用了标准的内嵌的代码,而不是有开发人员进行全部编码,同时编译执行的速度比解释执行的速度快的多,因此在开发过程中应尽量使用数据窗口和DATASTORE..即使是必须用 SQL 语句的时候,也应该尽量将它们定义为存储过程(特别是在多用户的环境中),以提高应用程序的性能.  二、数据窗口的编程和执行 数据窗口是PB最值得被称道的, 其具有如下特点: 1. 多种显示方式. 2. 多种编辑方式. 3. 使用方法简单. 4. 具有多种报表形式. 5. 可实现屏幕滚动. 6. 可实现数据的有效性校验. 7. 执行性能显著提高. 8. 编程工作变少. 9. 可以在数据窗口内部实现数据哭的更新. 下面, 我将介绍一些用于提高数据窗口性能的技术. 1. 减少连接数据库的次数 连库操作是非常影响执行速度的操作. 因此在程序中,一旦与数据库连接后就应当尽量保持与数据库的连接, 减少连接数据库的次数.PowerBuilder 提供里两个函数来建立数据窗口与事务对象的连接: SetTrans() SetTransObject() 在程序中应当尽量使用 SETTRANSOBJECT(), 因为SETTRANS() 函数在每次调用 RETRIEVE(), UPDATE() 等函数之后, 都要执行数据库的连接和断开操作. 2. 下拉数据窗口与表的连接 对于数据库服务器来说, 表的连接操作是一项非常大的开销, 而 PowerBuilder 提供的下拉数据窗口在某些情况下可以代替表的连接操作.例如, 为了在数据窗口上显示用户的电话号码和姓名:如果用表的连接的方法, 数据窗口对应的 SQL 语句应是这样的: SELECT "DA_DH"."DHHM", "DA_HTH"."DWM" FROM "DA_HTH", "DA_DH" WHERE ("DA_HTH"."DHHM"="DA_DH"."DHHM") 同样的程序可用下拉数据窗口来完成, 这里不再具体介绍.但是, 应当注意, 以上两种方法究竟哪一种数据更快, 与表的结构, 表的数量, 连接的方法等均有关系, 应当具体分析. 3. 共享数据 在一个应用程序中, 某些数据需要频繁的使用, 如果在每次使用时都从数据库中进行检索, 则需占用大量的服务器资源和网络资源. 为了减少开销, 可以在客户端对这些数据只进行一次检索, 然后允许其它任务共享这些数据. 例如, 如果有两个数据窗口, 都需要从第三方表中检索出用户的电话号码, 且此列用下拉数据窗口给出. 如果每次都对电话号码进行检索, 则性能较低. 因此, 可以单独建立一个关于电话号码的数据窗口. 在每次打开窗口时, 首先将电话号码检索到此数据窗口中, 然后另外两个数据窗口中关于电话号码的下拉数据窗口可以共享此数据窗口中的数据. 在窗口的 OPEN 事件中编写如下程序: dw_1.settransobject(sqlca) dw_2.settransobject(sqlca) dw_3.settransobject(sqlca) // 检索 dw_1 dw_1.retrieve() // 使 DW_2 的下拉数据窗口共享 DW_1 datawindowchild child1 dw_2.getchild('dhhm',child1) child1.settransobject(sqlca) dw_1.sharedata(child1) // 使 DW_2 的下拉数据窗口共享 DW_1 datawindowchild child2 dw_3.getchild('dhhm',child2) child2.settransobject(sqlca) dw_1.sharedata(child1) 使用这种方法, 避免了各个数据窗口间物理的拷贝数据, 因此减少了空间上的开销,提高了应用程序的综合性能. 4. 数据窗口间数据的拷贝 如果需要在数据窗口间共享数据, 应当尽量使用 SHAREDATA() 函数, 但是, SHAREDATA() 函数并不是物理地在数据窗口间拷贝数据, 如工在显示数据的同时, 还要对数据进行操作, 则需要进行数据的拷贝. 例如, 要求将 DW_1 中选定的行拷贝到 DW_2 中: 在窗口的 OPEN 事件中编程: dw_1.settransobject(sqlca) dw_2.settransobject(sqlca) dw_1.retrieve() 在数据窗口 DW_1 的 ROWFOCUSCHANGED 事件中编写下列程序: long lr lr = dw_1.selectrow(0,false) lr = dw_1.getrow() lr = dw_1.selectrow(lr,true) 要完成从 DW_1 到 DW_2 的拷贝工作, 有两种方法: 第一种: 在按钮 "拷贝" 的 CLICKED 事件中编程 long lr lr = dw_1.getselectedrow(0) dw_1.rowscopy(lr,lr,primary!,dw_2,100,primary!) 执行程序, 利用 PowerBuilder PROFILER 得出所需时间为 1.7034(百分之一秒) 第二种: 在按钮 "拷贝" 的 CLICKED 事件中编程 dw_2.object.data = da_1.object.data.selected 执行程序, 利用 PowerBuilder PROFILER 得出所需时间为 0.8062(百分之一秒) 5. 数据窗口属性的访问和修改 A. 数据窗口属性的访问 在程序中访问数据窗口的属性有下列几种方法: A1. 采用点表达式访问 A2. 应用多个独立的 DESCRIBE() 函数访问 A3. 只使用一个 DESCRIBE() 函数, 采用复合参数访问多个属性 上面三中方法, 通常第一种方法最慢, 第三种方法最快. 例如: 在窗口的 OPEN 事件中 DW_1.SETTRANSOBJECT(SQLCA) DW_1.RETRIEVE() 第一种方法: 在检索按钮的 CLICKED 事件中编程. string dx, dy, dh, dw dx = dw_1.object.da_dh.x dy = dw_1.object.da_dh.y dx = dw_1.object.da_dh.height dy = dw_1.object.da_dh.width st_1.text =dx+","+dy+","+dh+","+dw 第二种方法: string dx, dy, dh, dw dx=dw_1.describe("da_dh.x") dx=dw_1.describe("da_dh.y") dx=dw_1.describe("da_dh.height") dx=dw_1.describe("da_dh.width") st_1.text =dx+","+dy+","+dh+","+dw 第三种方法: string dx, dy, dh, dw st_1.text=dw_1.describe("da_dh.x" +& "da_dh.y" +& "da_dh.height" +& "da_dh.width") 实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差. B. 数据窗口属性的修改 在程序中修改数据窗口的属性有下列几种方法: A1. 采用点表达式修改 A2. 应用多个独立的 MODIFY() 函数访问 A3. 只使用一个 MODIFY() 函数, 采用复合参数访问多个属性 上面三中方法, 通常第一种方法最慢, 第三种方法最快. 例如: 在窗口的 OPEN 事件中 DW_1.SETTRANSOBJECT(SQLCA) DW_1.RETRIEVE() 第一种方法: 在检索按钮的 CLICKED 事件中编程. DW_1.SETREDRAW(FALSE) dw_1.object.da_dh.x = 18 dw_1.object.da_dh.y = 16 dw_1.object.da_dh.height = 100 dw_1.object.da_dh.width = 200 DW_1.setredraw(true) st_1.text =dx+","+dy+","+dh+","+dw 第二种方法: DW_1.SETREDRAW(FALSE) dw_1.modify("da_dh.x = 18") dw_1.modify("da_dh.y = 16") dw_1.modify("da_dh.height = 100") dw_1.modify("da_dh.width = 200") dw_1.setredraw(true) 第三种方法: dw_1.modify("da_dh.x=18" +& "da_dh.y=16" +& "da_dh.height=100" +& "da_dh.width=200") 实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差.注意, 在方法一和方法二中, 都使用的 setredraw() 函数以减少屏幕的重绘, 否则, 执行速度将严重下降. 6. 数据窗口中数据的访问 在程序中, 经常会需要动态的修改数据窗口中的数据. 对此, PB 提供了多种方法, 各种方法在性能上会有一些差异. A. 数据窗口中数据的访问 目的: 将数据窗口中的电话号码存放在一个数组中.请比较下面两中方法. 方法一: string da_dh[] long ll,i ll = dw_1.rowcount() for i = ll to 1 stet -1 da_dh[i] = dw_1.getitemstring(i,"dhhm") next 方法二: string da_dh[] da_dh[] = dw_1.object.dhhm.current 测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显. B. 数据窗口中数据的修改 目的: 修改数据窗口中的电话号码列的值. 请比较下面两中方法. 方法一: dw_1.setitem(i,"dhhm",l_name) 方法二: dw_1.object.name[i] = l_name 测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显. 7. 数据窗口事件对性能的影响 对于数据窗口控制中经常发生的事件, 应当尽量减少其中的程序代码. 特别是如下事件: A. itemchanged b. editchanged c. itemfocuschanged d. pbm_dwnkey e. rowfocuschanged f. retrieverow 在这些事件中的任何处理程序, 都会降低应用程序的处理速度. 所以应当尽量减少这些事件中的处理程序, 必要时, 可以考虑只将重要的代码放在这些事件中, 而将剩余的代码放在一个传递的事件中. 例如,如果需要用到数据窗口的 ROWFOCUSCHANGED 事件,可以为数据窗口定义一用户事件 "UE_RE",而在数据窗口的 ROWFOCUSCHANGED 事件中写如下代码: PARENT.postevent("ue_re") 在 UE_RE 事件中再编写相应的程序代码,如: string code dw_1.selectrow(0,false) dw_1.selectrow(rownum,true) code = getitemstring(dw_1,rownum,"dhhm") dw_2.retrieve(code) 另外, 为了获得当前行号,应尽量使用数据窗口的 CURRENTROW 变量,而少用 GETROW() 函数。 8、 数据窗口的列名称与列编号 对数据窗口的某列进行访问, 可以采用该列的名称, 也可以使用该列的编号, 例如: 采用列编号: dw_1.object.data[ll_row,2] dw_1.getitemstring(3,2) 采用列名称表示某列: dw_1.object.article_text[ll_row] dw_1.getitemstring(3,"dhhm") dw_1.setitem(3,"date",1999-03-31) ... 对于以上两种方法, 如果只进行一次查询, 在速度上并没有太大的区别,如过需要循环访问数据窗口上的某一列, 则速度上的差异就表现的比较明显,才用第一种方法要快, 但是程序的可读性比较差。但是, 在使用函数时(如 GETITEM() 和 setitem() ), 执行速度往往没有很大差别。 9、 计算域 数据窗口的计算域会对数据的操作性能产生影响。 如果数据窗口中包含许多复杂的计算域,将严重影响数据窗口的执行速度。 本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( ProgramFan.Com ) 【编程爱好者论坛】 本栏最新文章 pb中压缩整理access数据库文件(mdb) (2005-3-7)PowerBuilder数据窗口中记录颜色的隔层显示 (2005-2-13)PB8.0应用程序编译发布技术研究 (2005-2-13)如何在PB中制作特殊形状数据窗口或按钮 (2005-1-29)PB和EAServer共筑多层应用架构 (2005-1-4)PB中的数据窗口自动刷新技术 (2005-1-4)浅析PowerBuilder下动态SQL语句 (2005-1-4)PB中读取地磅BCD解码 (2004-9-29)PB通过OLEObject使用Word (2004-9-29)在PowerBulider中读写IC卡 (2004-9-23) 文章分类 C/C++文章 Visual Basic Visual C++ C++ Builder Visual Foxpro PowerBuilder Delphi ASP ASP.net JAVA WINDOWS编程 VB.net JSP 游戏开发 汇编语言 数据库开发 Visual C# XML PHP 算法 Linux文章 最新文章 Delphi环境下利用TWAIN实现对扫描仪的控制PHP开发者常犯的10个MySQL错误 C语言编程程序的内存如何布局在Linux下灵活使用expect脚本的小窍门VB.Net调用存储过程并得到返回值ASP.NET中的代码分离JAVA中sleep()、wait()、yield()、join()方法浅析详解VB.NET对象浏览器作用体现探索ASP.NET中Tailspin TravelUI层奥秘老生常谈:从VB6迁移到VB.netOracle中最易忽视的两个重要进程探秘Java 7新增垃圾回收器G1特性在Asp.net MVC中使用RepeaterJava按字节长度截取字符串Java解析XML文件的四种方法Java和.NET互操作:应该放弃Web Service吗熟知Linux操作系统紧急情况处理方法用PHP的PEAR DB模块编写数据库脚本(8)图形和图像编程(一)(7)Visual Studio菜单和工具条编程实战 最新招聘信息 关于本站 - 网站导航 - 广告服务 - //--> 诚邀加盟 - 联系站长 - 友情链接 - 赞助本站 Copyright&copy; 1999-2013 Programfan.com. All Rights Reserved 网站制作&维护:Hannibal Email: webmaster@pfan.cn -