如何在javascript中优化代码
我认为(下面的)代码是优化的(只需使用比相同逻辑的初始版本更少的变量)。如何在javascript中优化代码,javascript,arrays,performance,optimization,Javascript,Arrays,Performance,Optimization,我认为(下面的)代码是优化的(只需使用比相同逻辑的初始版本更少的变量)。 我如何才能真正知道它是否得到了适当的优化 在优化过程中应考虑哪些因素? 这是密码( ) 功能处理(arr){ var处理=[]; 对于(变量i=0,len=arr.length;i 1){ 对于(var j=0,jlen=nodes.length;j广义上的优化将涉及简化代码、预计算重复使用的结果,以及组织代码以便重用更多的结果 您的fiddle代码在分析中产生了以下结果 Logical LOC: 26 Mean par
功能处理(arr){
var处理=[];
对于(变量i=0,len=arr.length;i 1){
对于(var j=0,jlen=nodes.length;j广义上的优化将涉及简化代码、预计算重复使用的结果,以及组织代码以便重用更多的结果
您的fiddle代码在分析中产生了以下结果
Logical LOC: 26
Mean parameter count: 3
Cyclomatic complexity: 7
Cyclomatic complexity density: 27%
Maintainability index: 104
代码行(LOC)–表示代码中的大致行数。计数基于IL代码,因此不是源代码文件中的精确行数。非常高的计数可能表示某个类型或方法试图做太多的工作,应该拆分。它还可能表示该类型或方法可能难以维护
可维护性指数–计算一个介于0和100之间的指数值,表示代码的相对易维护性。高值意味着更好的可维护性。颜色编码评级可用于快速识别代码中的故障点。绿色评级介于20和100之间,表示代码具有良好的可维护性不可维护性。黄色评级介于10和19之间,表示代码可适度维护。红色评级介于0和9之间,表示可维护性较低
圈复杂度–衡量代码的结构复杂度。它是通过计算程序流中不同代码路径的数量来创建的。具有复杂控制流的程序将需要更多的测试来实现良好的代码覆盖率,并且不易维护
使用javascript代码检查代码复杂性
参考文献:
(为您提供了优化时应牢记的不同技术)当前,您的代码具有O(n^2)
复杂性。这是由过程中arr
的外循环引起的,然后调用findIndexes
,它再次循环arr
您可以将其简化为一个O(n)
算法,该算法在数组中循环两次:
function process(arr) {
var result = [];
var counter = {}, counts = {};
var len = arr.length;
for(var i = 0; i < len; i++){
var value = arr[i];
counter[value] = 1;
counts[value] = (counts[value] || 0) + 1;
}
for(var i = 0; i < len; i++){
var value = arr[i];
if(counts[value] == 1) {
result.push(value);
} else {
result.push(value + "(" + counter[value]++ + ")");
}
}
return result;
}
功能处理(arr){
var结果=[];
变量计数器={},计数={};
var len=阵列长度;
对于(var i=0;i
您可以在单个循环中完成:
function process2(arr) {
var out = arr.slice(0),
seen = {},
len = arr.length,
i, key, item, count;
for (i = 0; i < len; ++i) {
key = out[i];
item = seen[key];
if (!item) {
// firstIndex, count
seen[key] = item = [i, 0];
}
count = ++item[1];
if (count > 1) {
if (count === 2) {
out[item[0]] = key + '(1)';
}
out[i] = key + '(' + count + ')';
}
}
return out;
}
// input
var arr = ['aa', 'bb', 'bb', 'aa', 'cc', 'dd', 'cc', 'ff']
console.time('p2');
console.log(process2(arr));
console.timeEnd('p2');
功能处理2(arr){
var out=arr.slice(0),
seen={},
len=arr.长度,
i、 键、项、计数;
对于(i=0;i1){
如果(计数==2){
out[项目[0]]=键+'(1)';
}
out[i]=key+'('+count+');
}
}
返回;
}
//输入
var arr=['aa','bb','bb','aa','cc','dd','cc','ff']
控制台时间('p2');
console.log(process2(arr));
控制台。时间结束('p2');
从基准测试来看,process2
大约比process1
快2倍。这只是解决问题的第一步。还有另一种方法可以在较少更改的情况下优化代码:
在您的特定情况下,尽管所有以前的条目都已处理过,但您仍会遍历每个新找到的条目的整个数组,因此应该可以通过将当前索引传递给FindIndex来进一步优化:
function findIndexes(arr,val, fromIndex){
var node = [];
for(var i=fromIndex,len=arr.length;i<len;i++){
if(arr[i] === val){
node.push(i);
}
}
return node;
}
函数findIndex(arr、val、fromIndex){
var节点=[];
对于(var i=fromIndex,len=arr.length;i以下是一个不使用嵌套循环并使用对象存储键信息的示例:
var obj = {};
// loop over the array storing the elements as keys in the object
// if a duplicate element is found, increment the count value
for (var i = 0, l = arr.length; i < l; i++) {
var key = arr[i];
if (!obj[key]) obj[key] = { count: 0, level: 0 };
obj[key].count++;
}
// remove all the key/values where the count is 1
// ie there are no duplicates
for (var p in obj) {
if (obj[p].count === 1) delete obj[p];
}
// for each element in the original array, increase its 'level'
// amend the element with the count
// reduce the count
for (var i = 0, l = arr.length; i < l; i++) {
var key = arr[i];
if (obj[key] && obj[key].count > 0) {
obj[key].level++;
arr[i] = key + '(' + obj[key].level + ')';
obj[key].count--;
}
}
var obj={};
//在数组上循环,将元素作为键存储在对象中
//如果发现重复元素,则增加计数值
对于(变量i=0,l=arr.length;i0){
obj[key].level++;
arr[i]=key+'('+obj[key].level+');
obj[key]。计数--;
}
}
您的代码可能会针对性能进行优化,但为了可读性,这是另一个问题……如果这里没有问题,这似乎是属于您的。如果这会使您的页面不负责任(如果您使用html5),您可以使用web worker执行这种循环操作(在单独的线程中)@SebasSBM OP绝对不应该这样做,这是一种不好的做法。这是如何让它更快的呢?如果你能解释这些参数,那就太好了。谢谢你的参考链接。非常有用。回答了我的第二个问题。这并没有产生正确的输出:[“aa(1)”,“bb(1)”,“aa(1)”,“cc(1)”,“dd”,“cc(1)”,“ff”]
感谢您注意到,@Evantimboli。现在正确的结果是:[“aa(1)”,“bb(1)”,“bb(2)”,“aa(2)”,“cc(1)”,“dd”,“cc(2)”,“ff”]
我认为您的答案肯定会提高性能,我也会将其标记为答案
var obj = {};
// loop over the array storing the elements as keys in the object
// if a duplicate element is found, increment the count value
for (var i = 0, l = arr.length; i < l; i++) {
var key = arr[i];
if (!obj[key]) obj[key] = { count: 0, level: 0 };
obj[key].count++;
}
// remove all the key/values where the count is 1
// ie there are no duplicates
for (var p in obj) {
if (obj[p].count === 1) delete obj[p];
}
// for each element in the original array, increase its 'level'
// amend the element with the count
// reduce the count
for (var i = 0, l = arr.length; i < l; i++) {
var key = arr[i];
if (obj[key] && obj[key].count > 0) {
obj[key].level++;
arr[i] = key + '(' + obj[key].level + ')';
obj[key].count--;
}
}