2012-02-20 11 views
10

Tengo curiosidad por saber si todos los moldes en C# dan como resultado el boxeo, y si no, ¿todos los moldes son una operación costosa?¿Todos los moldes de C# resultan en boxeo/desempaquetado?

ejemplo tomado de Boxing and Unboxing (C# Programming Guide)

int i = 123; 
    // The following line boxes i. 
    object o = i; 

Esta línea obviamente hace que el boxeo (envolver del tipo int como un objeto). Esta es una operación que se considera costosa, ya que crea basura que se recogerá.

¿Qué hay de los moldes de 2 tipos diferentes de tipos de referencia? ¿Cuál es el costo de eso? puede medirse adecuadamente? (En comparación con el ejemplo anterior)

Por ejemplo:

public class A 
{ 
} 

public class B : A 
{ 
} 

var obj = new B(); 
var obj2 = (A)obj; // is this an "expensive" operation? this is not boxing 
+8

No se trata de un boxeo cuando se lanza de un tipo de referencia a otro. – BrokenGlass

+0

¿Se puede medir de forma adecuada? debería ser evitado? –

+0

Si bien el boxeo no está involucrado al convertir un tipo de referencia a otro, la conversión puede ser. La conversión de un tipo de referencia a otro tipo de referencia no relacionada puede ser costoso. –

Respuesta

22

Tengo curiosidad por saber si todas las conversiones en C# resultado en el boxeo.

No. Sólo las conversiones Resultados del boxeo en el boxeo, de ahí el nombre de 'conversiones de boxeo'. Conversiones de boxeo son todos incorporada en conversiones de tipos de valores a tipos de referencia, ya sea a una clase de la que hereda el tipo de valor o a una interfaz que implementa. (O a una interfaz compatible con una interfaz que implementa, mediante una conversión de referencia covariante o contravariante).

son todos conver siones una operación costosa?

No. Las conversiones de identidad son de costo cero porque el compilador puede eludirlas por completo.

¿Cuáles son los costos de las conversiones de referencia implícitas y explícitas?

Las conversiones de referencia implícitas son de costo cero. El compilador puede elide them enteramente. Es decir, la conversión de Jirafa a su tipo base Animal o Jirafa a su interfaz implementada tipo IAmATallMammal es gratuita.

Conversiones de referencia explícitas implican una comprobación de tiempo de ejecución para verificar que la referencia hace referencia a un objeto del tipo deseado.

Si el control del tiempo de ejecución es "costoso" o no depende de su presupuesto.

¿Puede ese costo medirse correctamente?

Sure. Decida qué recurso es relevante para usted, digamos, y luego mida cuidadosamente su consumo de tiempo con un cronómetro.

Una pregunta que no pidió, pero probablemente debería tener:

¿Cuáles son las conversiones más caros?

Las conversiones definidas por el usuario no son más que un azúcar sintáctico para una llamada a un método; ese método puede tomar arbitrariamente largo, como cualquier método.

Las conversiones dinámicas vuelven a iniciar el compilador en el tiempo de ejecución; el compilador puede tomar un tiempo arbitrariamente largo para realizar un análisis de tipo, dependiendo de qué tan difícil sea el problema de análisis que elija aplicar.

+1

Eric, ¿qué tal una conversión implícita hecha explícitamente por el programador? Supongo que eso también es eliminado por el compilador. (Ejemplo: 'var o = (object)" Some string "; return o.GetHashCode();') – phoog

+2

@phoog: Correcto. No hay necesidad de generar IL para eso; la referencia de cadena ya es compatible con la asignación de la variable. –

10

No.

Boxing significa poner un valor en una nueva instancia de tipo de referencia.

Los moldes estándar entre los tipos de referencia no dan lugar a ninguna asignación.
(moldes definidos por el usuario pueden hacer nada)

+0

"La conversión desde un tipo de referencia no genera ninguna asignación". No necesariamente cierto. – jason

+0

@Jason: Clarified – SLaks

+0

Votación eliminada. – jason

7

Tengo curiosidad por saber si todas las proyecciones en C# resultado en el boxeo,

Nº boxeo es un very special operation que significa tratar a una instancia de una tipo de valor como una instancia de un tipo de referencia. Para la conversión de tipo de referencia a la conversión de tipo de referencia, el concepto no juega ningún papel.

¿todos los modelos son costosos?

Respuesta corta: No.

Respuesta larga: Definir costoso. Aún así, sin embargo.

¿Qué hay de los moldes de 2 tipos diferentes de tipos de referencia? ¿Cuál es el costo de eso?

Bueno, ¿y si se trata solo de una conversión de referencia base derivada? Eso es DIFÍCILMENTE rápido porque no pasa nada.

Otras conversiones definidas por el usuario podrían ser "lentas", podrían ser "rápidas".

Este es "lento".

class A { public int Foo { get; set; } } 
class B { 
    public int Foo { get; set; } 
    static Random rg = new Random(); 
    static explicit operator A(B b) { 
     Thread.Sleep(rg.Next()); 
     return new A { Foo = b.Foo; } 
    } 
} 

Éste es "rápido".

class A { public int Foo { get; set; } } 
class B { 
    public int Foo { get; set; } 
    static Random rg = new Random(); 
    static explicit operator A(B b) { 
     return new A { Foo = b.Foo; } 
    } 
} 

var obj2 = (A)obj; // esta es una "cara" operación? esto no es boxeo

No, es "barato."

+0

operación costosa significa == si tengo un algoritmo que involucra bucle + casting (no boxeo), ¿es más inteligente diseñarlo de manera diferente, o es una operación trivial que no se considera de alto costo (en términos de tiempo de ejecución)) –

+0

@liortal: Depende. Si le preocupa el rendimiento, midalo. – SLaks

+0

Estoy interesado en entender cómo funciona esto más que preocupado específicamente por un golpe de rendimiento –

Cuestiones relacionadas