2011-01-15 12 views
5

Actualmente estoy creando una aplicación basada en web (= JavaScript) que usa muchos "puntos" (= vectores de tamaño pequeño y fijo). Hay básicamente dos maneras obvias de representarlos:¿Cuál es la forma más eficiente de manejar puntos/vectores pequeños en JavaScript?

var pointA = [ xValue, yValue ]; 

y

var pointB = { x: xValue, y: yValue }; 

Así traducir mi punto un poco sería el resultado:

var pointAtrans = [ pointA[0] + 3, pointA[1] + 4 ]; 
var pointBtrans = { x: pointB.x + 3, pointB.y + 4 }; 

Ambos son fáciles de manejar desde un programador punto de vista (la variante del objeto es un poco más legible, especialmente porque trato principalmente con datos 2D, rara vez con 3D y apenas con 4D, pero nunca más. Siempre cabe en x, y, z y w)

Pero mi pregunta es ahora:
¿Cuál es la forma más eficiente desde la perspectiva del lenguaje, teóricamente y en implementaciones reales?
¿Cuáles son los requisitos de memoria?
¿Cuáles son los costos de instalación de una matriz frente a un objeto?
...

Mis navegadores de destino son FireFox y los basados ​​en Webkit (Cromo, Safari), pero no estaría de más tener un gran (= rápido) experiencia bajo IE y Opera, así ...

+1

Mi sensación dice que los objetos consumen menos memoria: Un objeto es la estructura básica de datos en JS. Las matrices se construyen sobre objetos y proporcionan métodos adicionales. Pero la diferencia es probablemente insignificante. –

+1

Se almacenan métodos adicionales en 'Array.prototype'. Ninguna matriz los mantiene directamente. – galambalazs

Respuesta

0

Gracias por todas las respuestas y la entrada.Muy interesante fueron los resultados de la prueba escrita por galamalazs: http://jsperf.com/object-vs-array/2

Tomando todos los aspectos juntos conseguiremos:

  • matrices deben ser indexados por el número y no por la cadena (arr [0] vs. arr ['0'])
  • El rendimiento entre el objeto y el formulario de matriz difiere principalmente por implementación, no por tipo.
  • no hay un ganador, que cambia de una implementación a
  • implementaciones futuras de los navegadores conocidos hoy en día también podría cambiar quién está ganando - en ambos sentidos
  • En Cromo las matrices utilizará la mitad de la memoria del objeto - pero estamos hablando de 40 MB y 80 MB para un millón de instancias, es decir, de 40 a 80 bytes cada uno.
  • Se desconoce el consumo de memoria de otras implementaciones de JavaScript, pero probablemente también difiera tanto como el rendimiento.

Así que, al final, ambas opciones son sensatas y solo la legibilidad del código tomará la decisión.

Si se trata principalmente de almacenar datos con un trabajo trivial (como en mi proyecto actual), el modo Objeto es el camino a seguir. Un mouse.x y mouse.y muestra trivialmente la intención del desarrollador.

En aplicaciones principalmente orientadas matemáticamente con matemáticas vectoriales como transformaciones de coordenadas (especialmente yendo a 3D) la mejor manera sería el caso Array, ya que las multiplicaciones de matrices parecerían más nativas para el desarrollador y mostrarían su intención.

+0

también veo mi respuesta actualizada para más información. – galambalazs

1

Mi corazonada es que las matrices le dará un mejor rendimiento. (!)

dicho esto, el código ya es significativamente menos legible en su ejemplo de matriz que en el ejemplo de objeto. Es probable que las ganancias sean mínimas, por lo que sugiero que haga algunos cálculos básicos de evaluación comparativa y de la parte de atrás de la servilleta para poner un número real en la compensación.

Para empezar, usted podría

  • iniciar un temporizador
  • Constructo 1 miles de azar [X, Y] Arrays
  • acceder a sus campos de 1 millón de veces.
  • Repita con Objects y compare.

(!) - Un buen ejemplo de por qué el benchmarking es tan útil: las matrices son mejores para la creación, pero los objetos son mejores para el acceso, lo cual podría ser muy importante (según sus necesidades). galambalazs ha escrito una gran prueba para este caso: http://jsperf.com/object-vs-array

+1

Tiene razón en que solo un punto de referencia dará "la respuesta", pero actualmente JavaScript tiene un gran impulso para lograr implementaciones más rápidas y más rápidas. Temo que la decisión de diseño basada en los puntos de referencia actuales pronto quede obsoleta ... – Chris

+1

Tiene razón . De hecho, a menos que esté implementando algo con necesidades especiales de rendimiento (o la magnitud del intercambio forza mi mano), * siempre * estoy a favor de ahorrar tiempo al desarrollador frente a ahorrar tiempo de la máquina, particularmente en prototipos. Como cualquier desarrollo de software, Encapsulate Well y Do not Repeat Yourself, entonces la refactorización puede ocurrir más tarde sin mucho dolor. –

+0

Con Google V8, creo que la versión de clase será tan rápida como el código compilado de C++. –

5

Las matrices son más rápidas de crear, pero si se tiene en cuenta el tiempo de acceso, es al revés. También tenga en cuenta que constructor formulario es rápido para crear y acceder. Tiene lo mejor de ambas palabras en implementaciones modernas new Vector(x, y) - [Test] alt text

Navegadores probados:Chrome 10, Firefox 3.6, Firefox Beta 4.0b9, IE 9 Vista Previa 7, Opera 11

+1

+1 ¡Esta es una excelente respuesta! –

+2

El acceso a matrices y objetos casi no hace diferencia en Chrome 8. Pero la creación de matrices es mucho más rápida. –

+0

hmm ... Supongo que el acceso más lento para los valores de matriz es la coerción de un número a una cadena. Recuerde que las matrices * son * objetos, por lo que los índices de matrices siguen siendo propiedades de un objeto. 'arr [0]' y 'arr [" 0 "]' son funcionalmente iguales, pero el primero debe ser * ligeramente * más lento en teoría. –

Cuestiones relacionadas