如何使我的代码更快?
How do I make my code faster?
以下代码可以很好地实现我想在 netsuite 中实现的目标,但我无法找到使其更快的方法。我试着不经常使用系统 nlapi,但如果不提交记录,我似乎无法让它工作。任何指导将不胜感激。
function WonLost(type, name) {
if (name == 'custbody138') {
var recordid = nlapiGetRecordId();
var record = nlapiLoadRecord('estimate', recordid);
if ((nlapiGetFieldValue('custbody138')) == 'T') {
var itemsall = "";
var lineCount = parseInt(record.getLineItemCount('item'));
var x = 1;
while (x <= lineCount) {
nlapiSelectLineItem('item', x);
nlapiSetCurrentLineItemValue('item', 'custcol55', 'T', 'false');
nlapiCommitLineItem('item');
x++;
}
}
else {
var itemsall = "";
var lineCount = parseInt(record.getLineItemCount('item'));
var x = 1;
while (x <= lineCount) {
nlapiSelectLineItem('item', x);
nlapiSetCurrentLineItemValue('item', 'custcol55', 'F', 'false');
nlapiCommitLineItem('item');
x++;
}
}
}
}
有一个 overhead 的概念,我在大学里睡过,但我的基本理解是循环可能很昂贵。 (性能密集型)
因此,如果有 100 行并且您一次循环 1 行,那就是 100 次循环,但是如果您每次循环可以处理 5 行,那么它只有 20 次循环。叫做"loop unrolling"、http://en.wikipedia.org/wiki/Loop_unrolling
所以不要这样做...
while (x<= lineCount)
{
//do stuff on line x
x++;
}
试试这个...
while (x<= lineCount)
{
//do stuff on line x
//do stuff on line x+1
//do stuff on line x+2
//do stuff on line x+3
//do stuff on line x+4
x=x+5;
}
而且你还必须处理有 47 行的情况,所以你只循环到 ((int)(linecount/5)*5) 然后一次做一个迷你 1最后循环处理 46 和 47 (linecount%5)。
这会导致非常丑陋、不优雅的代码,但我发现它对性能非常有帮助,特别是在分块长 sql 查询时。您必须调整块大小,5 可能太小或太大都没有好处,因此调整它并记录您的时间,直到找到最佳点。
这是什么类型的脚本?
您似乎正在加载部署脚本的记录。这是完全没有必要的,您可以只使用 nlapi*
函数而不是 record.*
函数。加载整条记录是您可以执行的成本较高的操作之一。
- 删除您的
recordid
和 record
变量
- 将您的
record.getLineItemCount
调用替换为 nlapiGetLineItemCount
另一种方法是在客户端脚本的 Recalc 函数上将 'custcol55'
设置为 'T',这样您就不需要遍历整个项目列表。
以下代码可以很好地实现我想在 netsuite 中实现的目标,但我无法找到使其更快的方法。我试着不经常使用系统 nlapi,但如果不提交记录,我似乎无法让它工作。任何指导将不胜感激。
function WonLost(type, name) {
if (name == 'custbody138') {
var recordid = nlapiGetRecordId();
var record = nlapiLoadRecord('estimate', recordid);
if ((nlapiGetFieldValue('custbody138')) == 'T') {
var itemsall = "";
var lineCount = parseInt(record.getLineItemCount('item'));
var x = 1;
while (x <= lineCount) {
nlapiSelectLineItem('item', x);
nlapiSetCurrentLineItemValue('item', 'custcol55', 'T', 'false');
nlapiCommitLineItem('item');
x++;
}
}
else {
var itemsall = "";
var lineCount = parseInt(record.getLineItemCount('item'));
var x = 1;
while (x <= lineCount) {
nlapiSelectLineItem('item', x);
nlapiSetCurrentLineItemValue('item', 'custcol55', 'F', 'false');
nlapiCommitLineItem('item');
x++;
}
}
}
}
有一个 overhead 的概念,我在大学里睡过,但我的基本理解是循环可能很昂贵。 (性能密集型)
因此,如果有 100 行并且您一次循环 1 行,那就是 100 次循环,但是如果您每次循环可以处理 5 行,那么它只有 20 次循环。叫做"loop unrolling"、http://en.wikipedia.org/wiki/Loop_unrolling
所以不要这样做...
while (x<= lineCount)
{
//do stuff on line x
x++;
}
试试这个...
while (x<= lineCount)
{
//do stuff on line x
//do stuff on line x+1
//do stuff on line x+2
//do stuff on line x+3
//do stuff on line x+4
x=x+5;
}
而且你还必须处理有 47 行的情况,所以你只循环到 ((int)(linecount/5)*5) 然后一次做一个迷你 1最后循环处理 46 和 47 (linecount%5)。
这会导致非常丑陋、不优雅的代码,但我发现它对性能非常有帮助,特别是在分块长 sql 查询时。您必须调整块大小,5 可能太小或太大都没有好处,因此调整它并记录您的时间,直到找到最佳点。
这是什么类型的脚本?
您似乎正在加载部署脚本的记录。这是完全没有必要的,您可以只使用 nlapi*
函数而不是 record.*
函数。加载整条记录是您可以执行的成本较高的操作之一。
- 删除您的
recordid
和record
变量 - 将您的
record.getLineItemCount
调用替换为nlapiGetLineItemCount
另一种方法是在客户端脚本的 Recalc 函数上将 'custcol55'
设置为 'T',这样您就不需要遍历整个项目列表。