论坛首页 Web前端技术论坛

Laszlo 数据·通信·优化

浏览 7621 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-04-18  
在我最近一次看Laszlo的reference的时候,满眼都是关于性能的话题。
如果你尝试开发Laszlo的程序,下边这个问题很可能也是你急于要解决的:用javarpc获得一个List包含数以千计的User,然后将其填入dataset中,并让一个列表和这个dataset绑定,或者一些互动,几秒钟完成,或者说,至少不会出现脚本错误。
写程序的时候只用了10个测试数据,没啥性能不性能的,不超过3秒钟就出来了,后来有人问我100个会不会出错,“!”,赶紧多按两零,崩溃...
问题可能出在三个地方:
1、获得:从数据库中取得数据并且序列化传过来
2、填充:把javarpc结果填充到dataset中
3、显示:和dataset有牵连的各view,尤其是列表的绑定

LzLazyReplicationManager是一定要用的。但是也只需要用这个就够了,也就是说显示部分基本无可优化了。
仍然出现Flash脚本错误XXXX问你是否停止运行。(这个并不是绝对的,在我的计算机上就没有)

接着我又对填充作了优化,让他在系统每次LzLdle.onidle的时候填充一个,直到填充完。
我能找到的几台计算机上已经不会出错了,不知道其他计算机情况如何。

接着我对获得过程也作了优化,之前没有管hibernate的延迟加载的问题,是"from User"这样的,如果不急需应用对象的概念在Laszlo中操作,我觉得"select user.username,user.info from User as user"这样的语句似乎更好,我所说的优化也是来自这一方面,严格的说这不是Laszlo的性能问题了。

刚刚写了三个测试,也许能说明一些问题。
测试的内容是返回1000个Hs,Hs类型包括code,name,info和一个Set(lazy)类型的Product。分别记录获得和填充所需要的时间。点击“初始化...”开始。
测试(0):没有任何优化 view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test0.lzx?lzt=swf[/swf]
测试(1):使用lazy replication优化了显示部分 view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test1.lzx?lzt=swf[/swf]
测试(2):(1)+优化获取的部分,避免Hibernate的延迟加载错误 view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test2.lzx?lzt=swf[/swf]
测试(3):(2)+优化了填充的部分,在系统空闲的时候填入,虽然时间会长,但是完全避免了错误 view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test3.lzx?lzt=swf[/swf]
测试(4):jsp的数据源,lazy replication方式view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test4.lzx?lzt=swf[/swf]
测试(5):javarpc绑定列表的数据源,lazy replication方式view source
[swf width=500 height=120]http://linkingstar.com.cn/3c/laszlo/test5.lzx?lzt=swf[/swf]

这个测试可能会依赖于你本机的能力,第一个时间纯粹是网络速度影响的,第二个是填充的时间。
框架为Laszlo3.0rc1+Spring1.21+Hibernate3
   发表时间:2005-04-19  
偶的这台机器配置很差: PIII 700 378M memeory, 而且在测试上面东西得时候还开了一堆的应用.
测试的结果是: 获得数据的时间一般在1秒以内. 而填充list的时候, 要花去100多秒......而且被提示了N次脚本时间过长

得出的结论是: 偶得扔掉这台老机器了......

另外, 根据以前做C/S的习惯, 在list里面少于100个的时候, 用这种方式提供给用户选择还行, 如果数据量是N百个, 甚至上千的时候, 用list作为容器, 用户选择起来就很痛苦了, 不知道Laszlo有没有提供智能的combo-box控件: 用户可以输入值, 然后控件根据用户输入, 渲染出以这个值开头的list, 这样能避免生成过多的list item了, 性能就会好很多.
0 请登录后投票
   发表时间:2005-04-19  
昨天没写完就连不上javaeye了,嘿嘿……
我个人是十分不主张这样使用flash的,应该用友好的方式一点点地把数据给用户。不只可以分页,按照每天也可以

LzLazyReplicationManager,他的作用就是只会去画出来list.height/item.height+1个item,然后通过计算个数来确定scrollbar的位置。如果显式的使用它,比如我前边的最后一个测试,我是这样用的
<list shownitems="4" dataoption="lazy">
    <textlistitem datapath="hs_dataset:/hs/@code"/>
</list>

这就是那个list的全部代码。我还不会计算渲染它所需的时间,所以没写出来测试

测试3我刚刚修改过了,可能Readonly的计算机不会出错了。
我是这么优化的
<datapointer name="hsData" xpath="hs_dataset:/">
	<attribute name="bean"/>
	<attribute name="posi" type="number" value="0"/>
	<attribute name="length" type="number" value="0"/>
	<method name="fill" args="b"><![CDATA[
		while (selectNext();); deleteNode();;
		this.bean=b;
		this.posi=0;
		this.length=bean.length;
		_del = new LzDelegate(this, 'doFill', LzIdle, 'onidle');;
		Debug.write("start");;
		LzIdle.callOnIdle(_del);;]]> </method>
	<method name="doFill"><![CDATA[
		addNode("hs",null, {code:bean[posi++][0]});;
		if (posi==length); _del.unregisterAll();;]]> </method>
</datapointer>
0 请登录后投票
   发表时间:2005-04-19  
Readonly 写道
不知道Laszlo有没有提供智能的combo-box控件: 用户可以输入值, 然后控件根据用户输入, 渲染出以这个值开头的list, 这样能避免生成过多的list item了, 性能就会好很多.

我想如果要实现类似的功能就直接用xpath过滤就行了.
数据可以通过异步的方式监听获得,但是必须全部获得,后来的操作可以全部让xpath去做
Flash RIA的一个重要特点就是可以离线操作数据,Flex本身实现离线的大部分API,比如服务器上的准确数据用绿色,自己修改的还没有被服务器认可的用淡绿色,或者再有一个按钮显式的完成主动去同步的动作等等
Readonly的需求可以这样做,有一个inputtext t,t的ontext事件,ontext让datapoint去用xpath过滤,然后再显示结果。
0 请登录后投票
   发表时间:2005-04-19  
[list]测试4是laszlo的教程上通常使用的方法
测试3是用dp去addNode
测试5是在rpc的remoteCall上绑定dataset[/list:u]
这三种方法都不会受到list.size=1000的影响,理论上再多也无所谓
这里牵扯了两种通信方法,也牵扯了两种replication的方法
lazy replication有一个弊病,
引用

In this case the listitem will use lazy replication and the list will use a LzDataSelectionManager, instead of a LzSelectionManager. Some of the APIs for adding and removing items will not be available, but startup time will be significantly faster. In general, you can modify data through the data APIs , instead of using list methods. If you have created your own listitem class you should read more about the LzDatapath replication  attribute.

不久前我就遇到了,我想摊开一个使用datapath的basetabelement的子类,用了lazyreplication以后就不能修改了,一晚上都找不到解决的方法,(上边这段话我是最近才见到的。)以至于开始疑惑是不是rpc只适合做mutate的工作,而不适合获得并处理list。
这就是我为什么要写测试3的原因。测试3中的lazy是可有可无的,可能可以使用buffer来增加速度,理论上极限速度就是4或者5的情况吧,希望能在性能和简洁之间找到一种dirty的方法。顺便说一句xmlhttp或者dataobject的方式必不可少的需要lazy replication

通信上,使用xmlhttp这种方式(php,asp,py,当然都一样啦),可以做脱离lps的单独swf文件,也就是说可以做成RCP,但是rpc不可以,至少现在版本的laszlo还没有做到。
但是全部使用javarpc却可以简化服务器的编程,而且客户端的编程可以在灵活的基础上更加dirty
的确是各有利弊的

所以,你想要做起来简单,或者在之前的ww,struts等等的应用上尝试Laszlo,那么就用xmlhttp的src,何况这种做法有可能做成rcp
如果是从头做一个Laszlo应用,javarpc的确是首选,Flex的RemoteObject或者直接用Flash的AMF是一个道理。
0 请登录后投票
   发表时间:2005-06-28  
两个月以后的今天,在看这篇居然标为精华的帖子,不禁要打寒颤了,尤其是今天有人问我laszlo如何用javarpc和spring通信问题,我想给他指条明路的时候。
我就以现在的高度澄清一下这个问题,
laszlo和数据操作有关的核心控件是dataset,他无非就是内嵌的或者外部引用的一段xml数据,动态的或者静态的,你必须想清楚他为什么是datapointer的子类,而用若干datapointer对他做node操作以及xPathQuery
关于这方面,我认为Calendar就是超好的教程。

javarpc较之使用webwork做中间层,将大幅降低系统的耦合程度,而非回归jsp,因为,他根本就是在取消耦合。而且可以很随机应变。
简单的数据通信应用,examples里边的javarpc例子配合帮助,已经基本涵盖所有内容了。

下边有两个方面的问题:如何优化数据 和 如何取得大数据

关于优化,reference其实说得很明白了,我在这上边废了半天话,还没人家说得明白:(见reference:baselist)
引用
pooling
    If you will be changing the data that is represented by the list after it has been created, you can set dataoption="pooling". For more about pooling see the datapath pooling attribute and the example in list.
lazy
    If there are more items in the list than will be visible and all list items are the same size (for example, in a scrolling list or combobox), you should set dataoption="lazy". For more about lazy replication see the datapath lazy replication attribute, LzLazyReplicationManager, and the example in list.

这dataoption的属性其实就是list下加一个datapath。……再明白不过了,我不翻译了。总之你是获得大量数据的时候lazy就解决了一切问题。但是lazy会带来一些问题,如果有遇到问题的朋友在联系我吧。这和你的设计有关。

取得(po的list这种)数据,普遍来说有三种想法:
1、在cascade上做文章,在发送中做文章(如忽略所有Collection的子类)
2、在select的时候"个性化"一些,同过去的个别字段的方法来避免延迟加载的问题,(大家知道返回的list是Object数组的list,这会使得查错难上加难)
3、为需要的环节提供用例元素的包装类,
比如
想知道所有的用户的中文名和英文名,但是又不想知道其他信息,比如他们属于哪一个部门,这个部门又有什么用户,等等。
做法是这样:
List  user = find("from User as user");;
List result = new LinkedList();;
for (Iterator iter = user.iterator();;iter.hasNext();;);{
    WrapperUser wu = new WrapperUser((User);iter.next(););;
    result.add(wu);;
}

到时候去传输WrapperUser的List好了,如果要改,也只是改这个类的构造函数,想添加,换名字,悉听尊便。
我一般采用第三种,因为Laszlo中的xPathQuery和它可以配合得天衣无缝
How? 让这个remotecall返回值注入到某dataset,如:
引用
<remotecall funcname="getCustomers" dataobject="customerbook"/>

然后就跟操作所有的data一样了。只不过如果你用第二种方法返回的数据,可能会产生这样的xPathQuery:
引用
customerbook:/item/item[1]/item[2]/item

而方法三完全可以避免这一问题,因为你返回的是对象。
0 请登录后投票
   发表时间:2007-03-13  
Laszlo效率很低很消耗资源吗[url]
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics