¿Cuál es el razonamiento detrás de los vectores de Scala que tienen un factor de bifurcación de 32, y no algún otro número? ¿No permitirían los factores de ramificación más pequeños un mayor intercambio estructural? Clojure parece usar el mismo factor de ramificación. ¿Hay algo mágico en el factor de ramificación 32 que me falta?¿Por qué los vectores son tan superficiales?
Respuesta
Sería de gran ayuda si usted explicó lo que es un factor de ramificación es:
El factor de ramificación de un árbol o un gráfico es el número de niños en cada nodo.
Por lo tanto, la respuesta parece ser en gran parte aquí:
http://www.scala-lang.org/docu/files/collections-api/collections_15.html
vectores se representan como los árboles con un alto factor de ramificación. Cada nodo de árbol contiene hasta 32 elementos del vector o contiene hasta 32 otros nodos de árbol. Los vectores con hasta 32 elementos se pueden representar en un solo nodo. Los vectores con hasta 32 * 32 = 1024 elementos pueden ser representados con un único direccionamiento indirecto. Dos saltos desde la raíz del árbol al nodo de elemento final son suficientes para los vectores con hasta elementos, tres saltos para vectores con 2 , cuatro saltos para vectores con 2 elementos y cinco saltos para vectores con hasta 2 elementos. Entonces, para todos los vectores de tamaño razonable, la selección de un elemento implica hasta 5 selecciones de matriz primitiva. Esto es lo que quería decir cuando escribimos que el acceso a los elementos es "efectivamente tiempo constante".
Así que, básicamente, tenían que tomar una decisión de diseño sobre cuántos niños tener en cada nodo. Como explicaron, 32 parecía razonable, pero, si considera que es demasiado restrictivo para usted, entonces siempre podría escribir su propia clase.
Para obtener más información sobre por qué puede haber sido 32, puede mirar este documento, ya que en la introducción hacen la misma afirmación que antes, sobre el tiempo casi constante, pero este documento trata sobre Clojure, parece más que Scala.
No dude en editar mi pregunta para mejorar la claridad. – fredoverflow
Es el "tiempo de manera eficaz constante" para las actualizaciones. Con ese gran factor de ramificación, nunca tienes que ir más allá de 5 niveles, incluso para vectores de escala de terabytes. Aquí hay un video con Rich hablando sobre eso y otros aspectos de Clojure en el Canal 9. http://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure
La respuesta de James Black es correcta. Otro argumento para elegir 32 elementos podría ser que el tamaño de la línea de caché en muchos procesadores modernos es de 64 bytes, por lo que dos líneas pueden contener 32 entradas con 4 bytes cada una o 32 punteros en una máquina de 32 bits o una JVM de 64 bits con un tamaño de almacenamiento dinámico hasta 32 GB debido a la compresión del puntero.
Eliminado el comentario ahora, para evitar redundancia. –
La línea de caché moderna es de 64bytes. Los procesadores más nuevos y más recientes de Intel solo pueden tener 128 bytes. – Puppy
Simplemente agregando un poco a la respuesta de James.
Desde un punto de vista de análisis de algoritmo, porque el crecimiento de las dos funciones es logarítmico, por lo que se escalan de la misma manera.
embargo, en aplicaciones prácticas, teniendo saltos es un número mucho más pequeño de saltos que, por ejemplo, la base 2, lo suficiente para que lo mantiene más cerca de constante de tiempo, incluso para valores bastante grandes de N.
Estoy seguro de que seleccionaron 32 exactamente (a diferencia de un número mayor) debido a algún tamaño de bloque de memoria, pero la razón principal es la menor cantidad de saltos, en comparación con los tamaños más pequeños.
También recomendamos que vea este presentación sobre InfoQ, donde Daniel Spiewak discute vectores a partir de unos 30 minutos en: http://www.infoq.com/presentations/Functional-Data-Structures-in-Scala
- 1. ¿Por qué los vectores en caja son tan lentos?
- 2. ¿Por qué los arrays de arrays (vectores) son tan lentos?
- 3. ¿Por qué los iframes son tan lentos?
- 4. ¿Por qué son distintos los tipos de cadenas y vectores?
- 5. ¿Por qué los trabajos de Powershell son tan lentos?
- 6. Cierres: ¿por qué son tan útiles?
- 7. ¿Por qué mis rieles son tan lentos?
- 8. ¿Qué tan costosos son los eventos MySQL?
- 9. ¿Por qué las contraseñas bancarias son tan débiles?
- 10. ¿Por qué las matrices NumPy son tan rápidas?
- 11. ¿Por qué son tan caras las claves de firma?
- 12. ¿Por qué PropertyInfo SetValue y GetValue son tan lentos?
- 13. ¿Qué tan caros son los diccionarios de Python para manejar?
- 14. ¿Qué tan rápido son los nodos EC/2 entre ellos?
- 15. Scala: ¿Por qué los actores son livianos?
- 16. ¿Qué tan costosos son los argumentos del puntero NULL?
- 17. ¿Por qué los hilos IIS son tan preciados en comparación con los hilos regulares de CLR?
- 18. ¿Por qué las consultas WMI son tan lentas algunas veces?
- 19. ¿Qué tan pesados son los monitores de Java?
- 20. ¿Qué tan confiables son los sockets de dominio de Unix?
- 21. ¿Qué tan importantes son realmente los patrones de diseño?
- 22. ¿Qué tan seguros son los recursos en .NET?
- 23. ¿Qué tan portátiles son los archivos de haz Erlang?
- 24. ¿Los Singleton son realmente tan malos?
- 25. ¿Qué tan estables son las máquinas ec2?
- 26. ¿Son los cromos "appendChild" realmente tan lentos?
- 27. ¿Por qué los tipos de CLR sin firmar son tan difíciles de usar en C#?
- 28. ¿Por qué los manejadores de archivos son un recurso tan costoso?
- 29. ¿Por qué los archivos ejecutables de Haskell/GHC son tan grandes en tamaño de archivo?
- 30. ¿Qué tan geniales son los tipos de datos definidos por el usuario en SQL Server?
culpo a los medios de comunicación. – Shmiddty
Trolltember en su máxima expresión. – rlemon