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有一个被零除的结果。所以这甚至不是一个有效的解决方案。

然而,我想你想要一个"一般"的答案。当然,这种问题伴随着大量的"取决于"资格。这取决于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、Strings或Objects可以用作哈希键。看看haxe.ds.IntMap、haxe.ds.StringMap和haxe.dd.ObjectMap。(

示例1:常见的查找表可能会将数字整数"一周中的某一天"映射到该天所用的单词。假设day:Int总是0-6,则一个日期int到字符串的查找表将是:

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

现在trace('Today is a '+day_name_lut[Date.now().getDay()]);会告诉我们今天是星期几。这就是将一个整数映射到字符串,以实现VERY低成本。比函数调用或IntMap<String>更便宜。

示例2:示例StringMap可以用于按字符串值存储某个对象(例如,可能按name存储Person。(这将允许我们稍后按名称查找人员:

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);

这在缓存昂贵的操作时非常常见。想象一下,通过URL缓存HTTP响应。第二次从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或三元运算符编写分支。编译器和虚拟机经过优化,可以获取(可能可变的(代码,并将其归结为目标CPU的最佳指令。

二进制操作index & 1怎么样?

最新更新