MSDOTnet.org Forum Index
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

fastest way to construct a struct from a type?

 
Post new topic   Reply to topic    MSDOTnet.org Forum Index -> C Sharp
Author Message
not_a_commie



Joined: 11 Aug 2007
Posts: 1

PostPosted: Fri Sep 14, 2007 2:56 pm    Post subject: fastest way to construct a struct from a type? Reply with quote

It seems that the only way to construct a struct from a type is to use
Activator.CreateInstance. Is that true? Can anyone improve
(performance-wise) upon this function below:


///
/// Create an object of the given type
/// A default constructor is required to be successful.
/// A failure will return null.
///
/// The type of the object to create.
/// Arguments for the desired
constructor.
public static object CreateObject(Type type, params object[]
constructorParams)
{
if (type == null)
throw new ArgumentNullException("Type");
try
{
if (type.IsArray)
{
int[] dimensions = new int[constructorParams.Length];
for (int i = 0; i < constructorParams.Length; i++)
dimensions[i] = (int)constructorParams[i];
return Array.CreateInstance(type.GetElementType(), dimensions);
}
else if (type == typeof(string))
{
return "";
}
else
{
// the easy and slow way:
//return Activator.CreateInstance(type, constructorParams);
if (constructorParams == null || constructorParams.Length <= 0)
{
ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
if (ci == null) // stupid structs and their default
constructors....
return Activator.CreateInstance(type); // it does cache the most
recent 16 types

DynamicMethod dm = new DynamicMethod("MyCtor", type,
Type.EmptyTypes, typeof(ClassFactory).Module, true);
ILGenerator ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Nop);
ilgen.Emit(OpCodes.Newobj, ci);
ilgen.Emit(OpCodes.Ret);
return ((CtorDelegate)dm.CreateDelegate(typeof(CtorDelegate)))();
// we could cache these delegates with a type lookup
// but preparation time is really very minimal
// see here: http://blogs.msdn.com/haibo_luo/archive/2005/11/17/494009.aspx
// and here: http://blogs.msdn.com/haibo_luo/articles/494008.aspx
}
else
{
Type[] constructorTypes = new Type[constructorParams.Length];
for (int i = 0; i < constructorParams.Length; i++)
constructorTypes[i] = constructorParams.GetType();
// DynamicMethod is not quite as fast in this case
// where we don't have a delegate matching the function
// This should be really rare in deserialization, though
ConstructorInfo ci = type.GetConstructor(constructorTypes);
if (ci == null) // stupid structs and their default
constructors....
return Activator.CreateInstance(type); // it does cache the most
recent 16 types

return ci.Invoke(constructorParams);
}
// another thing we could do is cache IClonables and just return
cloned copies in that case
}
}
catch (Exception e)
{
if (e.InnerException is LicenseException)
throw e.InnerException;
throw new ClassFactoryException("Error constructing object " +
type.Name, e);
}
}
private delegate object CtorDelegate();

Archived from group: microsoft>public>dotnet>languages>csharp
Back to top
View user's profile Send private message
Nicholas Paldino [.NET/C#



Joined: 08 Aug 2007
Posts: 71

PostPosted: Thu Dec 13, 2007 4:52 pm    Post subject: Re: fastest way to construct a struct from a type? Reply with quote

Curious, can you create a generic version of this and then use
default(T) (where T is the type parameter)? If you can, then that might be
the easiest, and most maintainable solution.

Of course, if you are loading the type information (loading the name of
the type, that is) and don't have access to it at compile time, it won't
help.

Other than that, you can probably still go down the dynamic code
generation route. I would recommend an interface which would return an
object, and you would then create dynamic types implementing that interface.
It would imply create an instance of your structure for you. Then, you
would have a dictionary keyed by type which would return this interface
implementation, and then just call the method to return a new instance of
the value type.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

"not_a_commie" wrote in message @o80g2000hse.googlegroups.com...
> It seems that the only way to construct a struct from a type is to use
> Activator.CreateInstance. Is that true? Can anyone improve
> (performance-wise) upon this function below:
>
>
> ///
> /// Create an object of the given type
> /// A default constructor is required to be successful.
> /// A failure will return null.
> ///
> /// The type of the object to create.
> /// Arguments for the desired
> constructor.
> public static object CreateObject(Type type, params object[]
> constructorParams)
> {
> if (type == null)
> throw new ArgumentNullException("Type");
> try
> {
> if (type.IsArray)
> {
> int[] dimensions = new int[constructorParams.Length];
> for (int i = 0; i < constructorParams.Length; i++)
> dimensions[i] = (int)constructorParams[i];
> return Array.CreateInstance(type.GetElementType(), dimensions);
> }
> else if (type == typeof(string))
> {
> return "";
> }
> else
> {
> // the easy and slow way:
> //return Activator.CreateInstance(type, constructorParams);
> if (constructorParams == null || constructorParams.Length <= 0)
> {
> ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
> if (ci == null) // stupid structs and their default
> constructors....
> return Activator.CreateInstance(type); // it does cache the most
> recent 16 types
>
> DynamicMethod dm = new DynamicMethod("MyCtor", type,
> Type.EmptyTypes, typeof(ClassFactory).Module, true);
> ILGenerator ilgen = dm.GetILGenerator();
> ilgen.Emit(OpCodes.Nop);
> ilgen.Emit(OpCodes.Newobj, ci);
> ilgen.Emit(OpCodes.Ret);
> return ((CtorDelegate)dm.CreateDelegate(typeof(CtorDelegate)))();
> // we could cache these delegates with a type lookup
> // but preparation time is really very minimal
> // see here:
> http://blogs.msdn.com/haibo_luo/archive/2005/11/17/494009.aspx
> // and here: http://blogs.msdn.com/haibo_luo/articles/494008.aspx
> }
> else
> {
> Type[] constructorTypes = new Type[constructorParams.Length];
> for (int i = 0; i < constructorParams.Length; i++)
> constructorTypes[i] = constructorParams.GetType();
> // DynamicMethod is not quite as fast in this case
> // where we don't have a delegate matching the function
> // This should be really rare in deserialization, though
> ConstructorInfo ci = type.GetConstructor(constructorTypes);
> if (ci == null) // stupid structs and their default
> constructors....
> return Activator.CreateInstance(type); // it does cache the most
> recent 16 types
>
> return ci.Invoke(constructorParams);
> }
> // another thing we could do is cache IClonables and just return
> cloned copies in that case
> }
> }
> catch (Exception e)
> {
> if (e.InnerException is LicenseException)
> throw e.InnerException;
> throw new ClassFactoryException("Error constructing object " +
> type.Name, e);
> }
> }
> private delegate object CtorDelegate();
>
Back to top
View user's profile Send private message
Ben Voigt [C++ MVP]



Joined: 08 Aug 2007
Posts: 189

PostPosted: Thu Dec 13, 2007 6:19 pm    Post subject: Re: fastest way to construct a struct from a type? Reply with quote

"Nicholas Paldino [.NET/C# MVP]" wrote in
message @microsoft.com...
> Curious, can you create a generic version of this and then use
> default(T) (where T is the type parameter)? If you can, then that might
> be the easiest, and most maintainable solution.
>
> Of course, if you are loading the type information (loading the name of
> the type, that is) and don't have access to it at compile time, it won't
> help.
>
> Other than that, you can probably still go down the dynamic code
> generation route. I would recommend an interface which would return an

No dynamic code generation needed (well the JIT will be generating code, but
it always does that).

> object, and you would then create dynamic types implementing that
> interface. It would imply create an instance of your structure for you.
> Then, you would have a dictionary keyed by type which would return this
> interface implementation, and then just call the method to return a new
> instance of the value type.

For the zero (or fixed) parameter case, construct a delegate from the
ConstructorInfo and store those in a dictionary. Then creating multiples of
the same type is as cheap as a delegate call.

See http://msdn2.microsoft.com/en-us/library/53cz7sc6.aspx

>
>
> --
> - Nicholas Paldino [.NET/C# MVP]
> - mvp@spam.guard.caspershouse.com
>
> "not_a_commie" wrote in message
> @o80g2000hse.googlegroups.com...
>> It seems that the only way to construct a struct from a type is to use
>> Activator.CreateInstance. Is that true? Can anyone improve
>> (performance-wise) upon this function below:
>>
>>
>> ///
>> /// Create an object of the given type
>> /// A default constructor is required to be successful.
>> /// A failure will return null.
>> ///
>> /// The type of the object to create.
>> /// Arguments for the desired
>> constructor.
>> public static object CreateObject(Type type, params object[]
>> constructorParams)
>> {
>> if (type == null)
>> throw new ArgumentNullException("Type");
>> try
>> {
>> if (type.IsArray)
>> {
>> int[] dimensions = new int[constructorParams.Length];
>> for (int i = 0; i < constructorParams.Length; i++)
>> dimensions[i] = (int)constructorParams[i];
>> return Array.CreateInstance(type.GetElementType(), dimensions);
>> }
>> else if (type == typeof(string))
>> {
>> return "";
>> }
>> else
>> {
>> // the easy and slow way:
>> //return Activator.CreateInstance(type, constructorParams);
>> if (constructorParams == null || constructorParams.Length <= 0)
>> {
>> ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
>> if (ci == null) // stupid structs and their default
>> constructors....
>> return Activator.CreateInstance(type); // it does cache the most
>> recent 16 types
>>
>> DynamicMethod dm = new DynamicMethod("MyCtor", type,
>> Type.EmptyTypes, typeof(ClassFactory).Module, true);
>> ILGenerator ilgen = dm.GetILGenerator();
>> ilgen.Emit(OpCodes.Nop);
>> ilgen.Emit(OpCodes.Newobj, ci);
>> ilgen.Emit(OpCodes.Ret);
>> return ((CtorDelegate)dm.CreateDelegate(typeof(CtorDelegate)))();
>> // we could cache these delegates with a type lookup
>> // but preparation time is really very minimal
>> // see here:
>> http://blogs.msdn.com/haibo_luo/archive/2005/11/17/494009.aspx
>> // and here: http://blogs.msdn.com/haibo_luo/articles/494008.aspx
>> }
>> else
>> {
>> Type[] constructorTypes = new Type[constructorParams.Length];
>> for (int i = 0; i < constructorParams.Length; i++)
>> constructorTypes[i] = constructorParams.GetType();
>> // DynamicMethod is not quite as fast in this case
>> // where we don't have a delegate matching the function
>> // This should be really rare in deserialization, though
>> ConstructorInfo ci = type.GetConstructor(constructorTypes);
>> if (ci == null) // stupid structs and their default
>> constructors....
>> return Activator.CreateInstance(type); // it does cache the most
>> recent 16 types
>>
>> return ci.Invoke(constructorParams);
>> }
>> // another thing we could do is cache IClonables and just return
>> cloned copies in that case
>> }
>> }
>> catch (Exception e)
>> {
>> if (e.InnerException is LicenseException)
>> throw e.InnerException;
>> throw new ClassFactoryException("Error constructing object " +
>> type.Name, e);
>> }
>> }
>> private delegate object CtorDelegate();
>>
>
Back to top
View user's profile Send private message
Ben Voigt [C++ MVP]



Joined: 08 Aug 2007
Posts: 189

PostPosted: Thu Dec 13, 2007 6:54 pm    Post subject: Re: fastest way to construct a struct from a type? Reply with quote

"Ben Voigt [C++ MVP]" wrote in message
news:%23oG9ozbPIHA.4880@TK2MSFTNGP03.phx.gbl...
>
> "Nicholas Paldino [.NET/C# MVP]" wrote
> in message @microsoft.com...
>> Curious, can you create a generic version of this and then use
>> default(T) (where T is the type parameter)? If you can, then that might
>> be the easiest, and most maintainable solution.
>>
>> Of course, if you are loading the type information (loading the name
>> of the type, that is) and don't have access to it at compile time, it
>> won't help.
>>
>> Other than that, you can probably still go down the dynamic code
>> generation route. I would recommend an interface which would return an
>
> No dynamic code generation needed (well the JIT will be generating code,
> but it always does that).
>
>> object, and you would then create dynamic types implementing that
>> interface. It would imply create an instance of your structure for you.
>> Then, you would have a dictionary keyed by type which would return this
>> interface implementation, and then just call the method to return a new
>> instance of the value type.
>
> For the zero (or fixed) parameter case, construct a delegate from the
> ConstructorInfo and store those in a dictionary. Then creating multiples
> of the same type is as cheap as a delegate call.
>
> See http://msdn2.microsoft.com/en-us/library/53cz7sc6.aspx

Sorry, this won't work because Delegate.CreateDelegate takes a parameter of
type MethodInfo, not MethodBase. My mistake.

>
>>
>>
>> --
>> - Nicholas Paldino [.NET/C# MVP]
>> - mvp@spam.guard.caspershouse.com
>>
>> "not_a_commie" wrote in message
>> @o80g2000hse.googlegroups.com...
>>> It seems that the only way to construct a struct from a type is to use
>>> Activator.CreateInstance. Is that true? Can anyone improve
>>> (performance-wise) upon this function below:
>>>
>>>
>>> ///
>>> /// Create an object of the given type
>>> /// A default constructor is required to be successful.
>>> /// A failure will return null.
>>> ///
>>> /// The type of the object to create.
>>> /// Arguments for the desired
>>> constructor.
>>> public static object CreateObject(Type type, params object[]
>>> constructorParams)
>>> {
>>> if (type == null)
>>> throw new ArgumentNullException("Type");
>>> try
>>> {
>>> if (type.IsArray)
>>> {
>>> int[] dimensions = new int[constructorParams.Length];
>>> for (int i = 0; i < constructorParams.Length; i++)
>>> dimensions[i] = (int)constructorParams[i];
>>> return Array.CreateInstance(type.GetElementType(), dimensions);
>>> }
>>> else if (type == typeof(string))
>>> {
>>> return "";
>>> }
>>> else
>>> {
>>> // the easy and slow way:
>>> //return Activator.CreateInstance(type, constructorParams);
>>> if (constructorParams == null || constructorParams.Length <= 0)
>>> {
>>> ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
>>> if (ci == null) // stupid structs and their default
>>> constructors....
>>> return Activator.CreateInstance(type); // it does cache the most
>>> recent 16 types
>>>
>>> DynamicMethod dm = new DynamicMethod("MyCtor", type,
>>> Type.EmptyTypes, typeof(ClassFactory).Module, true);
>>> ILGenerator ilgen = dm.GetILGenerator();
>>> ilgen.Emit(OpCodes.Nop);
>>> ilgen.Emit(OpCodes.Newobj, ci);
>>> ilgen.Emit(OpCodes.Ret);
>>> return ((CtorDelegate)dm.CreateDelegate(typeof(CtorDelegate)))();
>>> // we could cache these delegates with a type lookup
>>> // but preparation time is really very minimal
>>> // see here:
>>> http://blogs.msdn.com/haibo_luo/archive/2005/11/17/494009.aspx
>>> // and here: http://blogs.msdn.com/haibo_luo/articles/494008.aspx
>>> }
>>> else
>>> {
>>> Type[] constructorTypes = new Type[constructorParams.Length];
>>> for (int i = 0; i < constructorParams.Length; i++)
>>> constructorTypes[i] = constructorParams.GetType();
>>> // DynamicMethod is not quite as fast in this case
>>> // where we don't have a delegate matching the function
>>> // This should be really rare in deserialization, though
>>> ConstructorInfo ci = type.GetConstructor(constructorTypes);
>>> if (ci == null) // stupid structs and their default
>>> constructors....
>>> return Activator.CreateInstance(type); // it does cache the most
>>> recent 16 types
>>>
>>> return ci.Invoke(constructorParams);
>>> }
>>> // another thing we could do is cache IClonables and just return
>>> cloned copies in that case
>>> }
>>> }
>>> catch (Exception e)
>>> {
>>> if (e.InnerException is LicenseException)
>>> throw e.InnerException;
>>> throw new ClassFactoryException("Error constructing object " +
>>> type.Name, e);
>>> }
>>> }
>>> private delegate object CtorDelegate();
>>>
>>
>
>
Back to top
View user's profile Send private message
Marc Gravell



Joined: 08 Aug 2007
Posts: 46

PostPosted: Fri Dec 14, 2007 1:54 pm    Post subject: Re: fastest way to construct a struct from a type? Reply with quote

For info, if you are using .NET 3.5, you can use the Expression
namespace to do this without having to mess with the IL directly.
Example below - results first:

ConstructorInfo: 15564 [1000000]
Func: 52 [1000000]

So it takes 1/300th the time, which is nice.

Code follows; most of it is the test rig, and much of the rest could
be refactored to simplify [Jon - might fit in with ExpressionUtil -
would that make sense to you?]

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Diagnostics;
interface INamed { string Name { get; } int Counter { get; } }
class Demo : INamed {
public string Name { get; private set; }
public int Counter { get { return 1; } } // for checksum
public Demo(string name) {
Name = name;
}
}
class Program {
static void Main() {
Type type = typeof(Demo); // in reality by name of as a plugin
ConstructorInfo ci = type.GetConstructor(new[]
{typeof(string)});
ParameterExpression param =
Expression.Parameter(typeof(string), "name");
Func ctor = Expression.Lambda INamed>>(
Expression.New(ci, param), param).Compile();

const int COUNT = 1000000;
Stopwatch watch = new Stopwatch();

ci.Invoke(new[] { "hi" }); // for JIT
int check = 0;
watch.Start();
for (int i = 0; i < COUNT; i++) {
INamed instance = (INamed) ci.Invoke(new[] { "hi" });
check += instance.Counter;
}
watch.Stop();
Console.WriteLine("ConstructorInfo: {0} [{1}]",
watch.ElapsedMilliseconds, check);
watch.Reset();

ctor("hi"); // for JIT
check = 0;
watch.Start();
for (int i = 0; i < COUNT; i++) {
INamed instance = ctor("hi");
check += instance.Counter;
}
watch.Stop();
Console.WriteLine("Func: {0} [{1}]",
watch.ElapsedMilliseconds, check);


}
}
Back to top
View user's profile Send private message
Marc Gravell



Joined: 08 Aug 2007
Posts: 46

PostPosted: Fri Dec 14, 2007 2:07 pm    Post subject: Re: fastest way to construct a struct from a type? Reply with quote

Refactored helper methods, to allow simple usage, i.e.

Type type = typeof(Demo); // however you get this!
var ctor = type.Ctor();

i.e. a ctor that accepts a string, and we'll treat the result as an
INamed since such things are commonly based on an
interface/base-class. If not, can use Ctor

Marc

-----------

public static Func Ctor(this Type type) {
ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);

return Expression.Lambda>(
Expression.New(ci)).Compile();
}
public static Func Ctor(this Type
type) {
ConstructorInfo ci = type.GetConstructor(new[] {
typeof(TArg1) });
ParameterExpression param1 =
Expression.Parameter(typeof(TArg1), "arg1");

return Expression.Lambda>(
Expression.New(ci, param1), param1).Compile();
}
public static Func Ctor TResult>(this Type type) {
ConstructorInfo ci = type.GetConstructor(new[] {
typeof(TArg1), typeof(TArg2) });
ParameterExpression param1 =
Expression.Parameter(typeof(TArg1), "arg1"),
param2 = Expression.Parameter(typeof(TArg2), "arg2");

return Expression.Lambda>(
Expression.New(ci, param1, param2), param1,
param2).Compile();
}
public static Func Ctor TArg2, TArg3, TResult>(this Type type) {
ConstructorInfo ci = type.GetConstructor(new[] {
typeof(TArg1), typeof(TArg2), typeof(TArg3) });
ParameterExpression param1 =
Expression.Parameter(typeof(TArg1), "arg1"),
param2 = Expression.Parameter(typeof(TArg2), "arg2"),
param3 = Expression.Parameter(typeof(TArg3), "arg3");

return Expression.Lambda>(
Expression.New(ci, param1, param2, param3), param1,
param2, param3).Compile();
}
public static Func
Ctor(this Type type) {
ConstructorInfo ci = type.GetConstructor(new[] {
typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) });
ParameterExpression param1 =
Expression.Parameter(typeof(TArg1), "arg1"),
param2 = Expression.Parameter(typeof(TArg2), "arg2"),
param3 = Expression.Parameter(typeof(TArg3), "arg3"),
param4 = Expression.Parameter(typeof(TArg4), "arg4");

return Expression.Lambda TResult>>(
Expression.New(ci, param1, param2, param3, param4),
param1, param2, param3, param4).Compile();
}

Back to top
View user's profile Send private message
Display posts from previous:   
Related Topics:
Help: The type library has lots of unexpected struct type de Hi, We have a COM+ component developed in managed C++. After using regsvcs.exe to install the component, we checked the type library. For ..Net 2002, only the interface and COM object defined in the component are listed in tlb, but .Net 2003 gives a lot o

how to cast IntPtr type to struct type Hi all, how to cast an System.IntPtr value to struct type. Example: protected override void WndProc(ref m) { const int = 0x0047; if(m.Msg == { string str=""; str);

PInvoke: struct with char** Member as struct** Parameter in Following C code is given: typedef struct { LONG num_tables; /* number of tables */ CHAR **tables; /* table names */ CHAR *where; /* where clause */ } // Allocates memory for a future SE_

Cryptography -- Construct RSAParameter from a Constant Strin Hi All, I have a CONSTANT String (which can be converted to Byte Array) of fixed length. Based on this string I wish to make a RSAParameter rsaParam, which then can be imported to Dim rsa as Dim buffer

struct covnertion(VB->C#) problem hello, all. I am trying to convert a struct from VB to c# in order to use an old DLL. Here is the definition in VB Public Type CHost Host As String * 60 Port As String * 5 Info As String * 120 'Inof returned from host Timeout As String * 10 End T
Post new topic   Reply to topic    MSDOTnet.org Forum Index -> C Sharp All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group