none
Una consulta sobre funciones y objetos: es una mala practica hacer esto o por el contrario es eficiente? RRS feed

  • Pregunta

  • Entiendo que para liberar memoria de objetos se usa dispose().

    Para hacer el código más corto no suelo declarar objetos sino que, cuando me es posible, de frente lo retorno usando la propia  función.

    Por ejemplo:

    ---------------------------------------------------------------------

    Function MiFuncion() as object

       Return GetObject(algo)

    End Function

    ---------------------------------------------------------------------

    En el código anterior GetObject devuelve un objeto.

    Se pudo haber declarado una variable de objeto, inicializado con New y luego asignado el resultado de GetObject y finalmente retornar en la función dicho objeto pero implica como tres o cuatro líneas de código.

    La duda es, al asignarla así a la función, en esa sola línea, una vez que la función se ejecuta, la memoria ocupada por el objeto queda liberada? o se queda perdida en algún lugar de la memoria de la computadora? (porque no se usa dispose por ningún lado y por tanto no se libera por lo menos explícitamente)


    • Editado James-2016 viernes, 22 de enero de 2016 19:30
    viernes, 22 de enero de 2016 19:29

Respuestas

  • Maticemos un poco estas cosas:

    - Para liberar la memoria de objetos NO se usa Dispose. El Dispose solo se utiliza dentro de aquellos objetos que internamente encapsulan código no-gestionado (es decir, que no es de .net), para liberar los recursos (no necesariamente memoria) ocupados por dicho código. Dispose no libera la memoria ocupada por el código gestionado (de .net).

    - Si declaras una función así:

    Function MiFuncion() as object
       Dim obj as Object = GetObject(algo)
       Return obj
    End Function

    es perfectamente eficiente porque la variable obj se asigna en el stack y desaparece en cuanto se ejecuta el return, así que no pierdes nada en comparación con hacer directamente Return GetObject.

    - Pero si la declaras así:

    Function MiFuncion() as object
       Dim obj as New Object = GetObject(algo)
       Return obj
    End Function

    entonces estás haciendo una enorme tontería. El New es completamente superfluo aquí. Hace que se asigne un nuevo objeto vacío, y a continuación lo desperdicia sobreescribiendo su referencia con el resultado del nuevo objeto devuelto por GetObject. El anterior objeto creado por New se vuelve inalcanzable y queda a disposición del Garbage Collector, que liberará su memoria cuando ésta se vuelva escasa, o cuando el programa termine. Así que mucho cuidado, que no se te escape un "New" donde no se necesita.

    viernes, 22 de enero de 2016 20:51
  • Sí, el último código es equivalente y es eficiente. Pero no te ahorras una variable. Si desensamblas el código MSIL generado por el compilador, verás que llama al GetObject, guarda el valor en una variable interna autogenerada, y luego hace un Return con esa variable. Así que aunque no la veas en tu código fuente, de todas maneras la variable existe.

    La ventaja de escribirlo como "return getobject" es que queda más limpio y compacto. Y la ventaja de escribirlo en dos líneas, escribiendo expresamente la variable intermedia, es que si necesitas depurar el código puedes poner un punto de ruptura en esa línea y examinar el valor de la variable.

    sábado, 23 de enero de 2016 8:08

Todas las respuestas

  • Maticemos un poco estas cosas:

    - Para liberar la memoria de objetos NO se usa Dispose. El Dispose solo se utiliza dentro de aquellos objetos que internamente encapsulan código no-gestionado (es decir, que no es de .net), para liberar los recursos (no necesariamente memoria) ocupados por dicho código. Dispose no libera la memoria ocupada por el código gestionado (de .net).

    - Si declaras una función así:

    Function MiFuncion() as object
       Dim obj as Object = GetObject(algo)
       Return obj
    End Function

    es perfectamente eficiente porque la variable obj se asigna en el stack y desaparece en cuanto se ejecuta el return, así que no pierdes nada en comparación con hacer directamente Return GetObject.

    - Pero si la declaras así:

    Function MiFuncion() as object
       Dim obj as New Object = GetObject(algo)
       Return obj
    End Function

    entonces estás haciendo una enorme tontería. El New es completamente superfluo aquí. Hace que se asigne un nuevo objeto vacío, y a continuación lo desperdicia sobreescribiendo su referencia con el resultado del nuevo objeto devuelto por GetObject. El anterior objeto creado por New se vuelve inalcanzable y queda a disposición del Garbage Collector, que liberará su memoria cuando ésta se vuelva escasa, o cuando el programa termine. Así que mucho cuidado, que no se te escape un "New" donde no se necesita.

    viernes, 22 de enero de 2016 20:51
  • ok gracias por la respuesta me sirvió para comprender mejor el uso de New, sin embargo no responde del todo a mi pregunta, a lo mejor no me expliqué bien, aquí la planteo de nuevo.

    Me dices que este código es es perfectamente eficiente:

    Function MiFuncion() as object
       Dim obj as Object = GetObject(algo)
       Return obj
    End Function

    De acuerdo, pero como a mi me gusta reducir el código en lo posible mi pregunta es que si este código que es más compacto (y hace lo mismo que el anterior) también es eficiente (no uso el New), lo uso tal como está abajo:

    Function MiFuncion() as object
       Return GetObject(algo)
    End Function

    Es una sola línea y he comprobado que funciona pero no sé qué tan eficiente es.

    ¿me parece que es equivalente (y me "ahorro" una variable) o hay diferencia?
    • Editado James-2016 sábado, 23 de enero de 2016 0:29
    sábado, 23 de enero de 2016 0:21
  • Sí, el último código es equivalente y es eficiente. Pero no te ahorras una variable. Si desensamblas el código MSIL generado por el compilador, verás que llama al GetObject, guarda el valor en una variable interna autogenerada, y luego hace un Return con esa variable. Así que aunque no la veas en tu código fuente, de todas maneras la variable existe.

    La ventaja de escribirlo como "return getobject" es que queda más limpio y compacto. Y la ventaja de escribirlo en dos líneas, escribiendo expresamente la variable intermedia, es que si necesitas depurar el código puedes poner un punto de ruptura en esa línea y examinar el valor de la variable.

    sábado, 23 de enero de 2016 8:08
  • jaja ok, no me ahorro una variable, pero sí son equivalentes y cada cual con sus pro y sus contra. Es lo que quería saber, gracias por la respuesta.

    • Editado James-2016 domingo, 24 de enero de 2016 20:19
    domingo, 24 de enero de 2016 20:17