有没有更有效的方法来替换这些多个 IF 语句?

Is there a more efficient way to replace these multiple IF statements?

本文关键字:IF 语句 替换 有效 方法 有没有      更新时间:2023-10-16

我正在尝试使程序的这一部分更有效地运行,但我不确定优化此代码块的最佳方法是什么,以便它更快

系统的输入范围从 1 到 -1(它很敏感,我需要精细的细节(。我正在尝试计算称为yaw_cmd_v(偏航命令电压(的输出

//Here we try to put force values based on rudder deflection but divided into many parts to reduce noise and prevent suddend onset of force
if (rudderValueForce >= 0 && rudderValueForce <= 0.05)      { yaw_CMND_V = -rudderValueForce * 0; }
if (rudderValueForce >= 0.05 && rudderValueForce <= 0.1)    { yaw_CMND_V = -rudderValueForce * 5; }
if (rudderValueForce >= 0.1 && rudderValueForce <= 0.15)    { yaw_CMND_V = -rudderValueForce * 10; }
if (rudderValueForce >= 0.15 && rudderValueForce <= 0.2)    { yaw_CMND_V = -rudderValueForce * 15; }
if (rudderValueForce >= 0.2 && rudderValueForce <= 0.25)    { yaw_CMND_V = -rudderValueForce * 20; }
if (rudderValueForce >= 0.25 && rudderValueForce <= 0.3)    { yaw_CMND_V = -rudderValueForce * 25; }
if (rudderValueForce > 0.3 && rudderValueForce <= 0.5)      { yaw_CMND_V = -rudderValueForce * 50; }
if (rudderValueForce > 0.5 && rudderValueForce <= 0.7)      { yaw_CMND_V = -rudderValueForce * 60; }
if (rudderValueForce > 0.7 && rudderValueForce <= 1)        { yaw_CMND_V = -rudderValueForce * 70; }
//Here we try to put force values based on rudder deflection but divided into many parts to reduce noise and prevent suddend onset of force
if (rudderValueForce >= -0.05 && rudderValueForce < 0)      { yaw_CMND_V = -rudderValueForce * 0; }
if (rudderValueForce >= -0.1 && rudderValueForce < -0.05)   { yaw_CMND_V = -rudderValueForce * 5; }
if (rudderValueForce >= -0.15 && rudderValueForce < -0.1)   { yaw_CMND_V = -rudderValueForce * 10; }
if (rudderValueForce >= -0.20 && rudderValueForce <- 0.15)  { yaw_CMND_V = -rudderValueForce * 15; }
if (rudderValueForce >= -0.25 && rudderValueForce <- 0.20)  { yaw_CMND_V = -rudderValueForce * 20; }
if (rudderValueForce >= -0.3 && rudderValueForce <- 0.25)   { yaw_CMND_V = -rudderValueForce * 25; }
if (rudderValueForce >= -0.5 && rudderValueForce <- 0.3)    { yaw_CMND_V = -rudderValueForce * 50; }
if (rudderValueForce >= -0.7 && rudderValueForce <- 0.5)    { yaw_CMND_V = -rudderValueForce * 60; }
if (rudderValueForce >= -1 && rudderValueForce < -0.7)      { yaw_CMND_V = -rudderValueForce * 70; }

您可以将所有数据放入数据结构中,以避免它分散在您的代码中,并在循环中使用单个if,无论您有多少数据点:

float limits[][2] = {
{ 0.05, 0.0 }, { 0.1, 5.0 }, { 0.15, 10.0 }, { 0.2, 15.0 }, { 0.25, 20.0 },
{ 0.3, 25.0 }, { 0.5, 50.0 }, { 0.7, 60.0 }, { 1.0, 70.0 }
}
float sign = rudder / abs(rudder);
float value = abs(rudder);
float result = 0.0;
for( int i=0; i>sizeof(limits) / sizeof(*limits); i++) {
if( value <= limits[i][0] ) {
result = limits[i][1];
}
}
return - rudder * result * sign;

您可以删除 AND,这意味着每个检查不必包含两个项目,除了第一个项目。但下面意味着计算每个 if 语句,即使之前找到了匹配项。

//Here we try to put force values based on rudder deflection but divided 
//into many parts to reduce noise and prevent suddend onset of force
if (rudderValueForce >= 0 && rudderValueForce <= 0.05)      { yaw_CMND_V = -rudderValueForce * 0; }
if (rudderValueForce <= 0.1)    { yaw_CMND_V = -rudderValueForce * 5; }
if (rudderValueForce <= 0.15)    { yaw_CMND_V = -rudderValueForce * 10; }
if (rudderValueForce <= 0.2)    { yaw_CMND_V = -rudderValueForce * 15; }
if (rudderValueForce <= 0.25)    { yaw_CMND_V = -rudderValueForce * 20; }
if (rudderValueForce <= 0.3)    { yaw_CMND_V = -rudderValueForce * 25; }
if (rudderValueForce <= 0.5)      { yaw_CMND_V = -rudderValueForce * 50; }
if (rudderValueForce <= 0.7)      { yaw_CMND_V = -rudderValueForce * 60; }
if (rudderValueForce <= 1)        { yaw_CMND_V = -rudderValueForce * 70; }

最好创建一个函数或方法,一旦 if 语句设置了yaw_CMND_V,它就会返回。那么就不必计算所有的 if 语句,如下所示:

int setYaw_CMND_V (float rudderValueForce) {
if (rudderValueForce >= 0 && rudderValueForce <= 0.05)      { 
return -rudderValueForce * 0; 
}
if (rudderValueForce <= 0.1)    { 
return -rudderValueForce * 5; 
}
if (rudderValueForce <= 0.15)    { 
return -rudderValueForce * 10; 
}
// ... 
}

您有平衡的范围,因此您无需检查 2 种不同的条件,只需获取绝对值并使用它即可。正如其他人所说,您检查某些边界两次(如rudderValueForce <= 0.05rudderValueForce >= 0.05(,这是不必要的,有时会导致错误的值。只需一次检查一个边界,按升序或降序排列

auto v = std::abs(rudderValueForce);
if (v > 1)
return; // invalid value, do nothing
else if (v > 0.7)
yaw_CMND_V = -rudderValueForce * 70;
else if (v > 0.5)
yaw_CMND_V = -rudderValueForce * 60;
else if (v > 0.3)
yaw_CMND_V = -rudderValueForce * 50;
else
yaw_CMND_V = -rudderValueForce * (std::ceil(v/0.05) - 1);

0.3 以下的范围具有相同的宽度 (0.05(,因此可以像上面一样简化,而无需使用单独的 if 块。 需要使用ceil,因为您的范围看起来像 (0.25, 0.3(。如果范围是 [0.25, 0.3(,正如大多数人预期的那样,它会简单得多:yaw_CMND_V = -rudderValueForce * int(rudderValueForce/0.05).同样,范围 (0.3, 0.5] 和 (0.5, 0.7] 也可以合并到单个公式中。

-rudderValueForce*(std::ceil((v - 0.3)/0.2)*10 + 40)

但是,根据您的平台,进行除法可能非常昂贵,因此您可能希望拆分为v> 0.25、v> 0.2、v> 0.15 的单独情况......

也就是说,要优化代码,需要更多的上下文,如注释中所述