Haxe:将变量映射到两个值之一的效率

时间:2018-07-24 00:10:50

标签: if-statement math haxe

  

我觉得这个问题太笼统了,问得不好。改进建议将不胜感激。

说我有一个整数变量,我需要将其转换为其他两个值之一。如果变量为0,则它​​将保持为0,否则它将变为1。我可以想到两种方法来实现。

方法1:内联if / else分配。

function runFunc(input:Int):Void
{
    <script>
}

for (index in 0...5)
{
    runFunc(if (index == 0) {0;} else {1;});
}

方法2:除法和舍入。

function runFunc(input:Int):Void
{
    <script>
}

for (index in 0...5)
{
    runFunc(Math.round(index / index));
}

方法1 更加标准化,可以用于其他数据类型和其他值,但是方法2 似乎需要较少的处理能力(尤其是如果需要几乎总是可以完成)。

假设方法2 在取整方面没有问题,那么两种方法之间的时间差异是否足以考虑使用另一种方法? if / else语句和Math.round()之类的不同事物如何影响处理时间?

2 个答案:

答案 0 :(得分:2)

首先,您的方法2 除以零。因此,它甚至不是一个有效的解决方案。

但是,我假设您想要一个“一般”的答案。并且,当然,这种问题带有“取决于”资格的一吨。它取决于CPU的类型,编程语言,编译器可能进行的优化,运行时优化等。

但是,通常,相关操作的成本顺序大致为:

  1. 逻辑和算术运算最便宜
    • 其中,整数运算比浮点运算便宜。
  2. 分支(if和循环)的价格适中。
  3. 部门价格适中。
  4. 函数调用非常昂贵。

基本上,这是因为(分别):

  1. 这就是CPU的工作,并且它们经过优化以快速完成工作
  2. 分支代表两种可能的路径,它们可能减慢CPU并行化和优化的速度。
  3. 除法是一个多步骤的过程。
  4. 函数调用必须推入并弹出堆栈。

因此,我可能会打赌您上面的方法1 。而且,为清楚起见,我将在您的第一个示例中使用等效的三元运算符编写if语句:

for (index in 0...5)
{
    runFunc( index==0 ? 0 : 1 );
}

这对于映射一个简单的布尔值(索引为0或不是)是有好处的。但是,当映射变得更加复杂时呢?将一个值映射到另一个值时,通常有两种构造:查找表或哈希图。

如果您的键是整数,且介于一些最小值和最大值之间,则查找表很有用。如果您的键是可哈希的(通常可以将Ints,String或Objects用作哈希键。请查看haxe.ds.IntMaphaxe.ds.StringMaphaxe.ds.ObjectMap。)

示例1::常见的查询表可能会将数字整数“星期几”映射到当天使用的单词。假设day:Int始终为0-6,则字符串查询表的天整型为:

var day_name_lut = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ];

所以现在trace('Today is a '+day_name_lut[Date.now().getDay()]);tell us今天是星期几。这是为了将 VERY 低成本转换为整数到字符串。比函数调用或IntMap<String>便宜。

示例2:sample StringMap可以用于通过字符串值存储某些对象(例如,Person由其name存储)。 ),这将使我们稍后可以按名称查找人

var people_by_name = new StringMap<Person>();
var joe = new Person("Joe");
people_by_name.set(joe.name, joe);
var bob = new Person("Bob");
people_by_name.set(bob.name, bob);

这对于缓存昂贵的作品非常普遍。 Imagine caching an HTTP response的网址。第二次从StringMap查找要比再次返回响应要便宜得多。

---更新---

我还注意到您说的是“内联if / else分配”,

runFunc(if (index == 0) {0;} else {1;});

请注意,实际上编写if内联是使 绝对没有 的性能差异。它将执行与以下操作完全相同的操作:

var tmp = if (index == 0) {0;} else {1;}
runFunc(tmp);

这些也完全相同:

runFunc( if (index == 0) 0 else 1);
runFunc( (index == 0) ? 0 : 1);

这些类型的语义差异对代码的最终执行没有任何影响。无论您是内联编写,将其存储在tmp变量中还是使用if / else或三元运算符编写分支,处理器仍然必须计算并临时存储值以调用函数。编译器和VM经过优化,可以将您的(可能变量)代码提取为目标CPU的最佳指令。

答案 1 :(得分:0)

二进制op index & 1怎么样?