2011-12-18 3 views
6

Есть ли какое-либо преимущество в производительности при хранении массивов в векторе типа Array?AS3 Vector of Arrays

Вариант например 1

private var _arrays:Vector.<Array> = new Vector.<Array>(2); 
_arrays[0] = new Array(10); 
_arrays[1] = new Array(10); 

Вариант 2

private var _arrays:Array = new Array(2); 
_arrays[0] = new Array(10); 
_arrays[1] = new Array(10); 

Также я могу иметь вектор или векторы?

private var _vectors:Vector.<Vector> = new Vector.<Vector>(2); 

_vectors[0] = new Vector.<String>(10); 
_vectors[1] = new Vector.<String>(10); 

Спасибо,

Марк

+0

См. Мой обновленный ответ @ crooksy88. Я опубликовал тестовый код + результаты, которые показывают, что мой оригинал верен, и ответ weltraumpirat явно ошибочен. –

ответ

10

EDIT

Мой первоначальный ответ был неправильным для самой последней части, за исключением, и я должен извиниться за это. Я знал, что Vector имеет ровно четыре реализации «под капотом». (Вы можете найти декомпилированные источники из FP 10 playerglobal.swc в сообщении Роберта Пеннера here) Три из них предназначены для типов номеров (int, uint и Number). Один для типов объектов. Этот последний служит как уловка и принимает все классы, полученные из Object. Вот почему я предположил, что Vector.<Object> все еще быстрее, чем Array, полагаясь на the information regarding vectors and arrays available from Adobe.

Тем не менее, кажется, что эта информация неверна, или, по крайней мере, она оставляет некоторые важные части:

  1. Хотя Vector.<AnyClassDerivedFromObject> позволяет строгой типизации, эта информация типа оценивается только во время компиляции (так что вы получить больше безопасности типов), но не во время выполнения - таким образом, по существу преимущества строгих объектов ввода объектов не относятся к производительности. См. this blog post для получения дополнительной информации.

  2. Следовательно, единственные реализации Vector, которые быстрее, чем Array, являются единственными типами чисел (!).

На самом деле, я сделал обширное исследование по этому вопросу, и пришел к выводу, что в то время как Vector.<int> до 60% быстрее, чем массив целых чисел, все дериваты Vector.<Object> не равны только в скорости (т.е.Vector.<Object> выполняет те же действия, что и Vector.<String>, они также составляют около 20% медленнее чем Array. Я дважды и трижды проверил это, поэтому считаю, что результаты будут достаточно точными.

Верно, что векторы числового типа быстрее, поэтому вы должны использовать их для преимуществ производительности по сравнению с массивом. Но:

END EDIT

Только если вы собираетесь использовать sort(), sortOn() или любой другой из удобных функций сортировки массива, вы можете все-таки решили иначе, потому что они являются носителями функций, а также такой действительно быстро. Реализация собственных методов сортировки по Vector, вероятно, не будет соответствовать их скорости.

+1

Я не вижу, как «Вектор». 'может быть любым быстрее, чем' Array'. Не могли бы вы объяснить, почему это так? –

6

лично я не вижу каких-либо выигрыш в производительности. Если он есть, он будет минимальным. Весь смысл иметь векторный класс - строго ввести элементы массива. Но сам объект массива предназначен для хранения нескольких типов объектов или даже нетипизированных ... так что строго набирая вектор в практически нетипизированный контейнер, который может быть заполнен нетипизированным или множественным, различно типизированным содержимым ... при этом продуманном виде это просто логически звучит так, как будто это будет малоэффективно.

Update

Вот некоторые результаты тестов производительности, чтобы доказать свою точку зрения. Мы можем видеть, что, когда в условиях стресса, вектор массивов равна производительности как массив массивов, и в одном тесте, это на самом деле еще хуже:

/ ============================================================================================= 
            Array Tests            
=============================================================================================/
Testing Array of Arrays push performance: 
Total time for 100000 push calls on Array of Arrays: 24 

Testing Array of Arrays random assignment performance: 
Total time for 100000 random assignment calls on Array of Arrays: 40 

Testing Array of Arrays sequential read performance: 
Total time for 100000 sequential read calls on Array of Arrays: 14 

Testing Array of Arrays random read performance: 
Total time for 100000 random read calls on Array of Arrays: 41 
/=============================================================================================/

/============================================================================================= 
            Vector Tests            
=============================================================================================/
Testing Vector of Arrays push performance: 
Total time for 100000 push calls on Vector of Arrays: 24 

Testing Vector of Arrays random assignment performance: 
Total time for 100000 random assignment calls on Vector of Arrays: 49 

Testing Vector of Arrays sequential read performance: 
Total time for 100000 sequential read calls on Vector of Arrays: 14 

Testing Vector of Arrays random read performance: 
Total time for 100000 random read calls on Vector of Arrays: 41 
/=============================================================================================/

И тестовый код:

import flash.events.Event; 
import flash.utils.getTimer; 

//Performance timer related 
var startTime:Number; //ms 
// 

//Our two container types we're testing IO on 
var arrayOfArrays:Array = new Array(); 
var vectorOfArrays:Vector.<Array> = new Vector.<Array>(); 
// 

//Used to store a bunch of arrays we're going to use to test 
var testArrays:Array = new Array(); 
// 

var randomIndex:uint = 0; 
var i:uint = 0; 
var arr:Array; 

//Generate a bunch of arrays of mixed typed content 
for(i = 0; i < 100000; ++i) { 
    generateTestArray(); 
} 

/*====================================================================================================== 
***********************************  Array Tests  ********************************************* 
*=====================================================================================================*/ 
//Test push on array of arrays 
trace("Testing Array of Arrays push performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    arrayOfArrays.push(testArrays[i]); 
} 
trace("Total time for 100000 push calls on Array of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test random write on array of arrays 
trace("Testing Array of Arrays random assignment performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    randomIndex = Math.round(Math.random() * 99999) as uint; 
    arrayOfArrays[randomIndex] = testArrays[randomIndex]; 
} 
trace("Total time for 100000 random assignment calls on Array of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test sequential read on array of arrays 
trace("Testing Array of Arrays sequential read performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    arr = arrayOfArrays[i]; 
} 
trace("Total time for 100000 sequential read calls on Array of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test random read on array of arrays 
trace("Testing Array of Arrays sequential read performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    randomIndex = Math.round(Math.random() * 99999) as uint; 
    arr = arrayOfArrays[randomIndex]; 
} 
trace("Total time for 100000 random read calls on Array of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 
/*====================================================================================================*/ 


/*====================================================================================================== 
***********************************  Vector Tests  ********************************************* 
*=====================================================================================================*/ 
//Test push on vector of arrays 
trace("Testing Vector of Arrays push performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    vectorOfArrays.push(testArrays[i]); 
} 
trace("Total time for 100000 push calls on Vector of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test random write on vector of arrays 
trace("Testing Vector of Arrays random assignment performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    randomIndex = Math.round(Math.random() * 99999) as uint; 
    vectorOfArrays[randomIndex] = testArrays[randomIndex]; 
} 
trace("Total time for 100000 random assignment calls on Vector of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test sequential read on vector of arrays 
trace("Testing Vector of Arrays sequential read performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    arr = vectorOfArrays[i]; 
} 
trace("Total time for 100000 sequential read calls on Vector of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 

//Test random read on vector of arrays 
trace("Testing Vector of Arrays sequential read performance:"); 
startTime = getTimer(); 
for(i = 0; i < 100000; ++i) { 
    randomIndex = Math.round(Math.random() * 99999) as uint; 
    arr = vectorOfArrays[randomIndex]; 
} 
trace("Total time for 100000 random read calls on Vector of Arrays: " + (getTimer() - startTime)); 
trace(" "); 
// 
/*====================================================================================================*/ 

function generateTestArray():void 
{ 
    var newArray:Array = new Array(); 

    var totalItems:uint = Math.round(Math.random() * 50 + 1); 

    var i:uint = 0; 

    var dice:uint = 0; 

    for(i; i < totalItems; ++i) { 

     dice = Math.round(Math.random() * 5); 

     switch(dice) { 
      case 0: 
       newArray.push(new int(Math.random())); 
      break; 

      case 1: 
       newArray.push(new String(Math.random())); 
      break; 

      case 2: 
       newArray.push(new Array()); 
      break; 

      case 3: 
       newArray.push(new MovieClip()); 
      break; 

      case 4: 
       newArray.push(new Date()); 
      break; 

      case 5: 
       newArray.push(new Event(Event.COMPLETE, false, false)); 
      break; 

     } 
    } 

    testArrays.push(newArray); 
}