集算器的网格变量的存储无处不在。单元格的值可以很方便地在计算中引用,但是,也会带来占用内存的问题。当一个格子中的数据已经完成了参与计算的使命时,我们可以把它清除掉以减少对内存的占用。如果在获得中间数据之后,还需要继续复杂的计算,就尤其需要注意,应该把不再使用的单元格值清除掉,以减少对系统内存的消耗,这样可以有效地避免内存溢出。
比如下面这个问题:列出所有家用电器和食品类订单中总额排在前200名的交易记录,按商品名称排列。订单记录来源于Order_Appliances.txt和Order_Foods.txt两个文本文件,需要先把两个表中的数据汇总后,取得订单总额前200名的订单记录,再按照商品名称排序。
|
A |
1 |
=file("Order_Appliances.txt").import@t() |
2 |
=file("Order_Foods.txt").import@t() |
3 |
=A1|A2 |
4 |
=A3.top(200;-Amount).new(ID, PName,Type,Date,Amount) |
5 |
=A4.sort(PName) |
其中各单元格运算结果如下:
A1中的序表为Order_Appliances.txt中的订单记录:
A2的序表为Order_Foods.txt中的订单记录:
A3将前面两个序表中的记录简单合并在一起,为下一步的过滤做准备。
A4中选出销售额前200名的订单记录,并从中选出需要的字段生成新序表。由于这里需要按销售额从大到小排列,因此在top() 函数中,Amount前面有负号,此时获得的结果是按照销售额降序排序的:
A5中,按照需要,将销售额前200名的订单记录按照商品名称排序:
实际上,我们最终需要的结果仅是A5中的数据。在A4整理出所有订单记录的必要信息之后,原始表格A1与A2中的信息就已经不再需要了。如果在中间数据获得之后,清除掉不再使用的初始数据,可以降低对系统内存的占用,使得运算更为稳定。
因此,网格程序可以按照下面的方法整理:
|
A |
B |
C |
1 |
=file("Order_Appliances.txt").import@t() |
|
|
2 |
=file("Order_Foods.txt").import@t() |
|
|
3 |
=A1|A2 |
>A1.reset() |
>A2=null |
4 |
=A3.top(200;-Amount).new(ID, PName,Type,Date,Amount) |
>A3=null |
|
5 |
=A4.sort(PName) |
>A4=null |
|
当把单元格值设为null时,单元格中的值就会被完全清空,如C3和B4中的语句。C3中的语句将A2中的单元格值清空,且B4将A3中引用食品订单记录的数据同样清空后,原始的食品订单就不会保持在内存中了。
在B3中的T.reset() 函数则有所不同,它会清除掉序表中的所有记录,但仍保留其数据结构,执行完B3后A1的值如下:
在清除格值时,可以根据需要选择这两种方法,其中将格值置空的方法更为常用,只有确实需要保留序表的数据结构时,才应该选用T.reset()。
值得注意的是B5中的语句,在这里虽然把A4中的值置空,却是无法达到减少内存占用的效果的。原因在于,A5返回的结果是一个排列,而这个排列中的记录引用均来自于A4中的序表,即使A4置空,这些记录也仍然会在A5中引用,是不会被清除的。因此,如果利用将单元格值置空来清除内存,一定要明确原单元格中的数据是否仍然被使用。
另外需要说明的是,在A5中对A4中的记录进行了排序操作,但是,在排序操作中,并不会产生新记录。在A5中存储的只是记录排序后的指针,对内存的占用较小,并不用担心这种情况造成的内存损耗。
在一段代码执行后,有可能有一批单元格中的格值都需要清除,而只保留最终结果。如下面的例子:
|
A |
B |
1 |
=file("Order_Appliances.txt").import@t() |
|
2 |
=file("Order_Foods.txt").import@t() |
=A1|A2 |
3 |
=B2.top(200;-Amount).new(ID, PName,Type,Date,Amount) |
|
4 |
=A3.sort(PName) |
|
5 |
>A1=null |
>A2=null |
6 |
>B2=null |
>A3=null |
这里与前面的例子类似,A4中计算的目的是取得订单总额前200名的订单记录,并按商品名称排序。计算后,为了降低内存损耗,在A5,B5,A6和B6中将不再使用的格子中的格值清除。这样的写法显然显得有些繁琐,为此,在集算器中特别提供了clear命令:
|
A |
B |
1 |
=file("Order_Appliances.txt").import@t() |
|
2 |
=file("Order_Foods.txt").import@t() |
=A1|A2 |
3 |
=B2.top(200;-Amount).new(ID, PName,Type,Date,Amount) |
|
4 |
=A3.sort(PName) |
|
5 |
clear A1,A2,B2,A3 |
|
网格的执行效果和上面是相同的。A5中的clear命令,可以一次清除多个单元格中的格值。另外,在clear命令中还可以指定单元格区域,如:
|
A |
B |
1 |
=file("Order_Appliances.txt").import@t() |
|
2 |
=file("Order_Foods.txt").import@t() |
=A1|A2 |
3 |
=B2.top(200;-Amount).new(ID, PName,Type,Date,Amount) |
|
4 |
=A3.sort(PName) |
|
5 |
clear A1:B3 |
|
A5的clear命令中,A1:B3表示A1到B3格所在的矩形区域,即A1,B1,A2,B2,A3,B3所组成的区域,clear命令会清除所有这些单元格的格值。在clear命令中,单个单元格和单元格区域的写法可以同时使用。如A5中的clear命令也可以写为clear A1:B2,A3,效果是相同的。
再来看下面的网格:
|
A |
B |
1 |
[Order_Appliances.txt,Order_Foods.txt] |
=[0]*A1.len() |
2 |
for A1 |
=file(A2).import@t() |
3 |
|
=B2.top(100;-Amount) |
4 |
|
=B3.sort(PName) |
5 |
|
>B1(#A2)=B4 |
6 |
=B1.merge(PName) |
|
7 |
=A6.new(ID, PName,Type,Date,Amount) |
|
表中的计算和前面稍有不同。这个网格中的代码,根据A1中的文件名,读取出数据,并从每个表中获取订单总额前100名的记录,将其按商品名称排序后,结果作为1个成员存储在序列B1中。由于结果已各自按商品名称排序,因此可以在A6中将所有结果按商品名称归并。最终在A7中生成结果序表如下:
在这段代码中,A7中获得最终结果后,同样应该清除不再使用的格值。在清除格值时,除了前面介绍的指定单元格或区域,还可以指定区段的主格,如:
|
A |
B |
1 |
[Order_Appliances.txt,Order_Foods.txt] |
=[0]*A1.len() |
2 |
for A1 |
=file(A2).import@t() |
3 |
|
=B2.top(100;-Amount) |
4 |
|
=B3.sort(PName) |
5 |
|
>B1(#A2)=B4 |
6 |
=B1.merge(PName) |
|
7 |
=A6.new(ID, PName,Type,Date,Amount) |
clear A1:B1,A2:,A6 |
B7的clear命令中,A2:的写法和单元格区域类似,但没指定区域的结束格。这样的写法表示清除以A2为主格的区块中所有单元格的值,即清除第2~5行的所有单元格的格值。执行后,除了A7中的结果,其它单元格中的格值都被清除。