sentencia lenguaje else ejemplos c# optimization inline

c# - sentencia - lenguaje c if else ejemplos



Funciones en lĂ­nea en C#? (14)

¡Las expresiones Lambda son funciones en línea! Creo que C # no tiene un atributo adicional como en línea o algo así!

¿Cómo hacer "funciones en línea" en C #? No creo que entienda el concepto. ¿Son como los métodos anónimos? ¿Te gustan las funciones lambda?

Nota : Las respuestas tratan casi por completo con la capacidad de las funciones en línea , es decir, "una optimización manual o de compilación que reemplaza un sitio de llamada de función con el cuerpo del destinatario". Si está interesado en las funciones anónimas (también conocidas como lambda) , vea la respuesta de @jalf o ¿De qué es esto ''Lambda'' del que todos hablan? .


¿Quieres decir funciones en línea en el sentido de C ++? ¿En el que los contenidos de una función normal se copian automáticamente en línea en el sitio de la llamada? El efecto final es que no se produce ninguna llamada de función cuando se llama a una función.

Ejemplo:

inline int Add(int left, int right) { return left + right; }

Si es así, no, no hay C # equivalente a esto.

O ¿Quieres decir funciones que están declaradas dentro de otra función? Si es así, sí, C # admite esto a través de métodos anónimos o expresiones lambda.

Ejemplo:

static void Example() { Func<int,int,int> add = (x,y) => x + y; var result = add(4,6); // 10 }


C # no admite métodos (o funciones) en línea como lo hacen los lenguajes dinámicos como python. Sin embargo, los métodos anónimos y las lambdas se pueden usar para fines similares, incluso cuando se necesita acceder a una variable en el método de contención, como en el siguiente ejemplo.

static void Main(string[] args) { int a = 1; Action inline = () => a++; inline(); //here a = 2 }


Cody tiene razón, pero quiero dar un ejemplo de lo que es una función en línea.

Digamos que tienes este código:

private void OutputItem(string x) { Console.WriteLine(x); //maybe encapsulate additional logic to decide // whether to also write the message to Trace or a log file } public IList<string> BuildListAndOutput(IEnumerable<string> x) { // let''s pretend IEnumerable<T>.ToList() doesn''t exist for the moment IList<string> result = new List<string>(); foreach(string y in x) { result.Add(y); OutputItem(y); } return result; }

El optimizador Just-In-Time del compilador podría elegir alterar el código para evitar colocar repetidamente una llamada a OutputItem () en la pila, de modo que sería como si hubiera escrito el código así:

public IList<string> BuildListAndOutput(IEnumerable<string> x) { IList<string> result = new List<string>(); foreach(string y in x) { result.Add(y); // full OutputItem() implementation is placed here Console.WriteLine(y); } return result; }

En este caso, diríamos que la función OutputItem () estaba en línea. Tenga en cuenta que podría hacer esto incluso si también se llama al OutputItem () desde otros lugares.

Editado para mostrar un escenario con mayor probabilidad de estar en línea.


En caso de que sus ensamblajes sean ngen-ed, es posible que desee echar un vistazo a TargetedPatchingOptOut. Esto ayudará a ngen a decidir si los métodos en línea. Referencia de MSDN

Sin embargo, todavía es solo una sugerencia declarativa para optimizar, no un comando imperativo.


Estás mezclando dos conceptos separados. La incorporación de funciones es una optimización del compilador que no tiene impacto en la semántica. Una función se comporta igual si está en línea o no.

Por otro lado, las funciones lambda son puramente un concepto semántico. No hay ningún requisito sobre cómo deben implementarse o ejecutarse, siempre y cuando sigan el comportamiento establecido en la especificación de idioma. Pueden estar en línea si el compilador JIT lo desea, o no si no lo tiene.

No hay ninguna palabra clave en línea en C #, porque es una optimización que generalmente se puede dejar al compilador, especialmente en lenguajes JIT''ed. El compilador JIT tiene acceso a las estadísticas de tiempo de ejecución, lo que le permite decidir qué incluir en línea de manera mucho más eficiente de lo que puede al escribir el código. Una función estará en línea si el compilador lo decide, y no hay nada que puedas hacer al respecto. :)


Hay ocasiones en las que deseo forzar el código para ser alineado.

Por ejemplo, si tengo una rutina compleja en la que hay una gran cantidad de decisiones tomadas dentro de un bloque altamente iterativo y esas decisiones resultan en acciones similares pero ligeramente diferentes que deben llevarse a cabo. Considere, por ejemplo, un comparador de ordenamiento complejo (no basado en DB) donde el algoritmo de ordenación ordena los elementos de acuerdo con una serie de criterios diferentes no relacionados, como el que uno podría hacer si clasificara palabras de acuerdo con criterios gramaticales y semánticos para un lenguaje rápido sistema de reconocimiento. Tendría a escribir funciones de ayuda para manejar esas acciones con el fin de mantener la legibilidad y la modularidad del código fuente.

Sé que esas funciones auxiliares deben estar alineadas porque esa es la forma en que se escribiría el código si nunca fuera necesario que lo entendiera un humano. Sin duda, me gustaría asegurarme de que en este caso no haya ninguna función de sobrecarga de llamadas.


La declaración "es mejor dejar estas cosas en paz y dejar que el compilador haga el trabajo ..." (Cody Brocious) es un verdadero rubish. He estado programando código de juego de alto rendimiento durante 20 años, y todavía tengo que encontrar un compilador que sea lo suficientemente inteligente como para saber qué código debe estar en línea (funciones) o no. Sería útil tener una declaración "en línea" en c #, lo cierto es que el compilador simplemente no tiene toda la información que necesita para determinar qué función debe estar siempre en línea o no sin la sugerencia "en línea". Seguro que si la función es pequeña (de acceso), entonces podría estar automáticamente en línea, pero ¿qué pasa si son unas pocas líneas de código? No tiene sentido, el compilador no tiene forma de saberlo, no puede dejar eso en manos del compilador para obtener un código optimizado (más allá de los algoritmos).


Los métodos en línea son simplemente una optimización del compilador donde el código de una función se enrolla en el llamador.

No hay ningún mecanismo mediante el cual hacer esto en C #, y deben usarse con moderación en los idiomas en que son compatibles. Si no sabe por qué deberían usarse en algún lugar, no deberían serlo.

Edición: para aclarar, hay dos razones principales por las que deben usarse con moderación:

  1. Es fácil hacer binarios masivos utilizando inline en los casos en que no es necesario
  2. El compilador tiende a saber mejor que usted cuando algo, desde un punto de vista de rendimiento, debe estar en línea

Es mejor dejar las cosas en paz y dejar que el compilador haga su trabajo, luego haga un perfil y descubra si Inline es la mejor solución para usted. Por supuesto, algunas cosas solo tienen sentido estar en línea (en particular los operadores matemáticos), pero dejar que el compilador se encargue de ellas suele ser la mejor práctica.


No, no hay tal construcción en C #, pero el compilador JIT .NET podría decidir realizar llamadas de función en línea en el tiempo JIT. Pero en realidad no sé si realmente está haciendo tales optimizaciones.
(Creo que debería :-))


Sé que esta pregunta es sobre C #. Sin embargo, puede escribir funciones en línea en .NET con F #. ver: Uso de `inline` en F #


Sí. Exactamente, la única distinción es el hecho de que devuelve un valor.

Simplificación (no usar expresiones):

List<T>.ForEach una acción, no espera un resultado devuelto.

Así que un delegado de Action<T> sería suficiente ... diga:

List<T>.ForEach(param => Console.WriteLine(param));

es lo mismo que decir:

List<T>.ForEach(delegate(T param) { Console.WriteLine(param); });

la diferencia es que el tipo de parámetro y la eliminación del delegado se deducen por el uso y las llaves no se requieren en un método simple en línea.

Donde como

List<T>.Where toma una función, esperando un resultado.

Así que se esperaría una Function<T, bool> :

List<T>.Where(param => param.Value == SomeExpectedComparison);

que es lo mismo que

List<T>.Where(delegate(T param) { return param.Value == SomeExpectedComparison; });

También puede declarar estos métodos en línea y asignarlos a las variables IE:

Action myAction = () => Console.WriteLine("I''m doing something Nifty!"); myAction();

o

Function<object, string> myFunction = theObject => theObject.ToString(); string myString = myFunction(someObject);

Espero que esto ayude.


Actualización: según la respuesta de konrad.kruczynski , lo siguiente es cierto para las versiones de .NET hasta e incluyendo 4.0.

Puede usar la clase MethodImplAttribute para evitar que un método se inserte ...

[MethodImpl(MethodImplOptions.NoInlining)] void SomeMethod() { // ... }

... pero no hay manera de hacer lo contrario y forzarlo a estar en línea.


Finalmente, en .NET 4.5, el CLR permite que se sugiera / sugiera 1 método de alineación utilizando el valor de MethodImplOptions.AggressiveInlining . También está disponible en el maletero de Mono (comprometido hoy).

// The full attribute usage is in mscorlib.dll, // so should not need to include extra references using System.Runtime.CompilerServices; ... [MethodImpl(MethodImplOptions.AggressiveInlining)] void MyMethod(...)

1 . Anteriormente se usaba "fuerza" aquí. Como hubo algunos votos a la baja, intentaré aclarar el término. Como en los comentarios y la documentación, The method should be inlined if possible. Especialmente considerando Mono (que está abierto), hay algunas limitaciones técnicas mono-específicas considerando en línea o una más general (como funciones virtuales). En general, sí, esta es una sugerencia para el compilador, pero supongo que eso fue lo que se pidió.