这种循环判断如何优化呢

2015-03-20 10:31:24 +08:00
 xxxpara

for(x=0;x<8;x++){
if(x==0||x==8){
y=1;
}
if(x==1||x==7){
y=2;
}
if(x==2||x==6){
y=4;
}
else{
y=6;
}
for(y;y<6;y++)
{
//...
}
}

3979 次点击
所在节点    JavaScript
15 条回复
xylophone21
2015-03-20 10:58:07 +08:00
"优化"的目的是什么?
代码好看还是性能? 前者可以查表,后者忘了吧.
Magic347
2015-03-20 11:19:36 +08:00
方案一:预置一个类似映射关系的数组,计算过程直接读取
int Y[8] = {1, 2, 4, 6, 6, 6, 4, 2, 1}
for (int x = 0; x < 8; x++) {
int y = Y[x];
}

方案二:尝试建立动态的映射关系,计算过程中动态执行计算
int Y(int x) {
if (0 <= (x%8) && (x%8) <= 2) {
return power(2, x%8);
}
return 6;
}
for (int x = 0; x < 8; x++) {
int y = Y(x);
}

以上,就是简单的两种思路吧,
方案一基于空间换时间的思想,
可以节省相应的映射计算开销,保证较好的查询效率;

方案二基于时间换空间的思想,
如果可以找到比较高效的映射函数,
一方面不会浪费存储资源,另一方面也可以实现较好的执行效率
c742435
2015-03-20 11:25:15 +08:00
另外,如果使用switch-case 而不是连续的if,编译器会帮你创建楼上方案1的那种优化方式。
xxxpara
2015-03-20 11:28:27 +08:00
@Magic347 受教!
zhicheng
2015-03-20 11:42:25 +08:00
switch-case 大法好。C 语言里边最高级的表达式。

for (x = 0; x < 8; x++) {
switch (x) {
case 0:
case 8:
y = 1;
break;
case 1:
case 7:
y = 2;
break;
case 2:
case 6:
y = 4;
break;
default:
y = 6;
break;
}

for (; y < 6; y++) {
}
}
miterleo
2015-03-20 11:52:27 +08:00
@Magic347 方案二 (6 % 8 = 6)、(7 % 8 = 7)
drivedreams
2015-03-20 12:27:29 +08:00
很显然要用switch
haitongz
2015-03-20 12:37:23 +08:00
switch吧
luw2007
2015-03-20 13:30:37 +08:00
数组: [0, 1, 2, 3, 4, 5, 6, 7, 8]
1.=> [0, 1, 2, 3, 4, 3, 2, 1, 0] <= 按照下标5做镜像. f(y) = 4-|x-4|, 得到
2.=> [1, 2, 4, 8, 16, 8, 4, 2, 1] <= 按照需求做指数曲线 f(y) = 2 ** x

判断小于6 其实就是判断第一步中元素小于3.
由 f(y) < 3 得 4-|x-4| < 3, 进而得到 x> 5, 或者x<3 成立.
综上可得:

if (x<3 || x>5){
// 分开写可以简化绝对值
y = 2 ** (4-|x-4|)
}else{
y = 6
}

使用switch也可以.
guoguoer
2015-03-20 14:03:09 +08:00
支持 @Magic347 的方法1,
在输入和输出的数量有限的情况下,先做一次预计算,把表算出来。之后都查表。
otakustay
2015-03-20 15:04:01 +08:00
我来给你们展示下不可读的优化:

function for1() {}
function for2() {}
function for3() {}

var tasks = [for1, for2, for3, for3, for2, for1];
for (var i = 0; i < 8; i++) {
tasks[i]();
}
Magic347
2015-03-20 16:59:10 +08:00
@miterleo 多谢指正,粗心大意了 :)
@xxxpara 方案二的Y()可能实现的有些小问题,简单更正一下,

int Y(int x) {
if (6 <= x && x <= 8) {
x = 8 - x;
}
if (0 <= x && x <= 2) {
return power(2, x);
}
return 6;
}
Magic347
2015-03-20 17:08:31 +08:00
@xxxpara 另外数组应该至少有9个元素,外部x迭代值的边界条件也需要更正一下,再次更正一下两个方案 :)

方案一:
int Y[9] = {1, 2, 4, 6, 6, 6, 4, 2, 1}

for (int x = 0; x < 9; x++) {
int y = Y[x];
// do something else
}


方案二:
int Y(int x) {
if (6 <= x && x <= 8) {
x = 8 - x;
}
if (0 <= x && x <= 2) {
return power(2, x);
}
return 6;
}

for (int x = 0; x < 9; x++) {
int y = Y(x);
// do something else
}
br00k
2015-03-20 17:19:03 +08:00
这种自然建议switch,代码可读性也高很多。
libook
2015-03-21 18:03:58 +08:00
我第一眼也是想到了switch。
其实你要说明优化的方向,是可读性还是存储还是计算?
其实用javascript这么高级的语言,个人的观点是可读性比性能重要,所以优化主要是在可读性上优化,你的代码用switch就会有很好的可读性,容易维护。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/178168

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX