我正在写一个赌场游戏,我需要加密我通过套接字传递的所有数据,所以我想要尽可能多的性能,因为加密和解密可能会发生很多,而且我不会希望它有点滞后。
我的问题是,如果你有一个String
并希望高速获取它的角色myString.charAt(i)
或拥有var a:Array = myString.split('');
然后让它们像这样,那么性能会更快a[i];
我的for
周期可能会达到60-100次或更多次。提前致谢
答案 0 :(得分:4)
您可以随时测试自己,看看在您的情况下哪些更有效,以及在执行代码之前和之后使用getTimer是否重要:
var testTime:int;
var before:int = getTimer();
//You code here
testTime = getTimer() - before;
trace(testTime);
所以基本上,你输入两个算法并检查执行的时间。
编辑:Apocalyptic0n3自然是正确的。最好使用新的Date.time()而不是getTimer(),因为它在冻结时更准确。答案 1 :(得分:1)
benbjo的建议是坚实的。如果性能真的是一个问题,那么最好的测试用例就是你实际上要使用你的代码的情况,尤其是因为垃圾收集和JIT'er使得事情无法预测实际表现。
尽管如此,charAt
方法一般比split()
快20-50%。记忆方面应该没有太大的区别 - 两种方法都是为每个角色创建一个新的字符串。除此之外,split()
显然还会创建一个额外的数组。
这两种方法的比较:
的charAt:
var s:String = "";
for (var j:int = 0; j < len; j++)
{
// The string concat seems to be enough to confuse the JIT compiler.
s += v.charAt(j);
}
分裂:
var s:String = "";
var arr:Array = v.split("");
for (var j:int = 0; j < len; j++)
{
// The string concat seems to be enough to confuse the JIT compiler.
// Using just arr[j] seems to be unfairly optimized.
s += arr[j];
}
相关的已编译ABC字节代码在两者之间是可预测的相同,除了调用split,以及数组访问与调用charAt()
之外。换句话说,ASC编译器没有疯狂的优化特技(无论如何都是罕见的)。
10次运行,每次上述代码1000次迭代,在发布播放器上发布版本:
FP WIN 11,5,502,110 : #Runs #Iter Avg Min Max Iter
charAt :: string length: 50 : 10 1000 9.0 ms 6 ms 10 ms 0.0090 ms
split :: string length: 50 : 10 1000 13.0 ms 8 ms 19 ms 0.0130 ms
charAt :: string length: 500 : 10 1000 68.5 ms 58 ms 97 ms 0.0685 ms
split :: string length: 500 : 10 1000 100.5 ms 86 ms 136 ms 0.1005 ms
charAt :: string length: 1000 : 10 1000 149.3 ms 119 ms 202 ms 0.1493 ms
split :: string length: 1000 : 10 1000 201.2 ms 162 ms 261 ms 0.2012 ms
charAt :: string length: 2000 : 10 1000 283.8 ms 230 ms 378 ms 0.2838 ms
split :: string length: 2000 : 10 1000 326.9 ms 307 ms 423 ms 0.3269 ms
charAt :: string length: 4000 : 10 1000 575.8 ms 475 ms 752 ms 0.5758 ms
split :: string length: 4000 : 10 1000 665.0 ms 609 ms 888 ms 0.6650 ms
charAt :: string length: 5000 : 10 1000 650.9 ms 581 ms 915 ms 0.6509 ms
split :: string length: 5000 : 10 1000 863.4 ms 769 ms 1219 ms 0.8634 ms
charAt :: string length: 10000: 10 1000 1300.5 ms 1155 ms 1707 ms 1.3005 ms
split :: string length: 10000: 10 1000 1797.3 ms 1534 ms 2461 ms 1.7973 ms
平均值=每次运行的平均时间(1000次迭代)
最小=单次运行的最短时间
最大=单次运行的最长时间
Iter =单次迭代的平均时间。
运行之间的差异相当大,可能是由于在某些运行期间发生了垃圾收集。但结果始终有利于charAt()
。在每次运行之前进行一次split()
调用而不是在每次运行中重做它并没有太大的区别。换句话说,性能的差异确实在于访问数组比调用charAt()
慢。然而,这不是巨大的差异,例如,您可以使用indexOf
而不是正则表达式来搜索字符串。
一般来说,虽然它不是一个严格的规则,但对于像字符串操作这样的简单任务最明显的方法可能会更快。 FlashPlayer团队花了很多时间来优化字符串操作,连接等。
答案 2 :(得分:1)
好的,这对评论来说太过分了。
首先,很难说你想要做什么,为什么你需要比较这些东西,但正如我已经说过的那样。如果您正在研究序列化 - 学习使用内置序列化。我已经看到它发生了很多次,当有人重新发明轮子时,数量级在各种可能的方面,然后是内置的。真正做到这一点的唯一理由是,如果你正在学习如何运作。
当然,如果您计划处理数十万个文件 - 您可以使用C语言编写并在AIR中使用原生扩展或其他类似文件,这肯定会赢。
现在,如果您想知道处理字符串数据的最快方法,那么这不是我们的选择。最快的方法是将其加载到域的内存中,并使用所谓的“Alchemy操作码”来访问数据字节。如果字符串使用8位编码,这将非常快,如果它们使用Unicode,则速度不会太快。显然,如果您要测试之前建议的内容,这也会影响您的测试。
第二个最佳选项:由整数组成的向量,它是char代码。这些更好地优化并使用不同的内存分配模型。
第三快的可能是ByteArray
或BitmapData
。
但如果你在序列化中做一些愚蠢的事情,那么这一切都绝对不重要。为了做到这一点,你真的需要一个好的策略,你需要在良好的层面上理解信息理论,以预测压缩数据的方式或其他方式是否会减小规模,或者更容易或更快地实施等等。在这个领域中有许多不好的决定很好的例子变得流行。 Base64编码,XML和JSON格式是坚持不懈的设计的例子。
说到Flash,选择是绝对明显的,在各方面AMF都比你在桌面上的任何选项更好。你需要对你正在做的事情有一个非常深入的了解,自己动手并使其变得更好。
PS。还有一点需要注意:如果您不想使用charAt
进行其他分配 - 您可以使用substr
或substring
,因为这些不会导致重新分配,但会阻止源字符串从被解除分配到减去的字符串存在。