Durante una entrevista, el entrevistador mencionó que "se suele decir que struct es más rápido que class". Luego acuñó las preguntas: "¿Por qué? ¿Qué relación tiene con la memoria? ¿Dónde se almacena?"
Esta pregunta me parece capciosa y bastante difícil de responder en una entrevista oral, a través de una video llamada, donde no tengo materiales para ilustrar las ideas.
Más de un desarrollador de iOS dice que las estructuras viven en el stack y las clases en el heap.
Sin embargo, estrictamente hablando, Swift no puede garantizar dónde se almacenan los objetos (instancias de class) y los valores (instancias de struct).
¿class siempre vive en el heap?
Es cierto que la mayor parte de las veces se puede asumir que los objetos (instancias de class) viven el heap. Sin embargo, si el compilador logra determinar que el objeto es creado y destruido dentro del mismo "stack-frame", sin ninguna referencia hacia él, entonces podría ser almacenado en el stack.
Consideremos el siguiente ejemplo:
class Box {
var point: Point
}
struct Point {
let x: Int
let y: Int
}
func makeBox() -> Int {
let box = Box(point: Point(x: 1, y: 2))
return box.point.x
}
En el caso anterior, el compilador podría optimizar la creación de Box y no crear el objeto físicamente en el heap, sino mantenerlo en el "stack-frame" y retornar el valor x.
¿Dónde se almacena un valor de tipo struct?
En ocasiones, el valor de un struct es tan pequeño que puede vivir en un registro - Como es el caso de un Int o un Double.
Por otro lado, un valor de struct mayor a tres palabras de máquina -o sea 8x3=24 bytes en procesadores de 64 bits- se guarda en el heap. A este paquete de 3 palabras se lo denomina "Value Buffer" de un "Existential container".
Sin importar que el valor de un struct podría estar almacenado en un registro o en el heap, lo más importante a tener en cuenta es que los atributos dentro de un struct se almacenan de forma inline, donde sea que se necesite que estén.
Retomemos el ejemplo anterior de Point y Box:
struct Point {
let x: Int
let y: Int
}
Cuando necesite almacenar un Point, el compilador se asegura de que tenga suficiente espacio para almacenar tanto x como y, un atributo inmediatamente después del otro. Si Point está en el "stack", entonces tanto x como y van a estar allí. Si está en el "heap", lo mismo: x y y van a estar en el "heap".
¿Qué pasa cuando mantenemos una referencia de Point desde Box?
class Box {
var point: Point
}
Box puede estar almacenado en el "heap". Como Point se almacena "inline" donde sea que se necesite, entonces puede estar almacenado en el "heap".
Conclusión
En Swift no hay una relación directa entre struct y stack ni entre class y heap. struct y class definen semántica (valor vs referencia) pero la ubicación en memoria depende del análisis de escape y de las optimizaciones del compilador.
¿Cuál fue mi respuesta en la entrevista?
Tan pronto empecé a describir con detalle los cimientos para dar una respuesta elaborada, pude notar en el rostro del entrevistador que no le agradaba mi respuesta. Tuve miedo y decidí responder que, en términos generales, struct vive en el stack y class vive en el heap y a eso se debe su rapidez.

Top comments (0)