AS3のXML処理最適化

Filed under AS3, Flash
Tagged as , , ,

XML処理の速度についていろいろな方法があるがどの方法がよいのか、を見極められないシーンが多い。

一度処理速度について調べておきたいと思っていて、とりあえず一つだけ調べたのでその結果をメモしておきます。

属性取得の速度

比較してみたのは属性取得の速度。
E4Xライブラリを使って属性にアクセスする場合、次のような3種類のコードになります。

1
2
3
4
var xml:XML = <data><value id="10">20</value></data>;
// var id = xml.@id; .. 方法1
// var id = xml.@["id"]; .. 方法2
// var id = xml.attribute( "id" ); .. 方法3

後述するコードを使用して、これらの違いを比べてみました。

結論

比較するために使用したコードは後述しますが、私の環境では平均して方法1が最も高速で、続いて方法2、方法3、という結果になりました。方法1は方法3よりも20%速く、方法2よりも5%速い、という結果になりました。

たまーに結果が入れ替わることもありますが、それらはおそらくキャッシュや別プロセスなどの問題だと思われます。

文字列処理がワンクッション入ると遅くなる、ということなのではないだろうか、と推測します。

このエントリの結論「E4Xが使える環境では属性データは@でアクセスすべし」

テストコード

以下にテストに使用したコードを載せておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
var i:int;
var NUM_TEST:int    = 10;
var t1:int = 0, t2:int = 0, t3:int = 0, t4:int = 0;
System.gc();
for ( i = 0; i < NUM_TEST; i++ ){
  t1	+= func1();
  t2	+= func2();
  t3	+= func3();
}
System.gc();
for ( i = 0; i < NUM_TEST; i++ ){
  t3	+= func3();
  t1	+= func1();
  t2	+= func2();
}
System.gc();
for ( i = 0; i < NUM_TEST; i++ ){
  t2	+= func2();
  t3	+= func3();
  t1	+= func1();
}
trace("func1:" + t1 + ",\tfunc2:" + t2/t1 + ",\tfunc3:" + t3/t1);
 
private function func1():int
{
  var NUM_LOOP:int = 10000;
  var xml:XML = <data><value id="10">20</value></data>;
  var i:int = 0;
  var t:int = 0;
  var startTime:int = getTimer();
  for ( i = 0; i < NUM_LOOP; i++ ) {
    t += int(xml.value.@id);
  }
 
  return (getTimer() - startTime);
}
 
private function func2():int
{
  var NUM_LOOP:int = 10000;
  var xml:XML = <data><value id="10">20</value></data>;
  var i:int = 0;
  var t:int = 0;
  var startTime:int = getTimer();
  for ( i = 0; i < NUM_LOOP; i++ ) {
    t += int(xml.value.@["id"]);
  }
 
  return (getTimer() - startTime);
}
 
private function func3():int
{
  var NUM_LOOP:int = 10000;
  var xml:XML = <data><value id="10">20</value></data>;
  var i:int = 0;
  var t:int = 0;
  var startTime:int = getTimer();
  for ( i = 0; i < NUM_LOOP; i++ ) {
    t += int(xml.value.attribute("id"));
  }
 
  return (getTimer() - startTime);
}

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*