473,471 Members | 1,715 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

fastest way to construct a struct from a type?

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:
/// <summary>
/// Create an object of the given type
/// A default constructor is required to be successful.
/// A failure will return null.
/// </summary>
/// <param name="type">The type of the object to create.</param>
/// <param name="constructorParams">Arguments for the desired
constructor.</param>
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(CtorDelega te)))();
// we could cache these delegates with a type lookup
// but preparation time is really very minimal
// see here: http://blogs.msdn.com/haibo_luo/arch...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();

Sep 14 '07 #1
5 3249
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]
- mv*@spam.guard.caspershouse.com

"not_a_commie" <no********@gmail.comwrote in message
news:11**********************@o80g2000hse.googlegr oups.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:
/// <summary>
/// Create an object of the given type
/// A default constructor is required to be successful.
/// A failure will return null.
/// </summary>
/// <param name="type">The type of the object to create.</param>
/// <param name="constructorParams">Arguments for the desired
constructor.</param>
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(CtorDelega te)))();
// we could cache these delegates with a type lookup
// but preparation time is really very minimal
// see here:
http://blogs.msdn.com/haibo_luo/arch...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();
Dec 13 '07 #2

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote in
message news:E7**********************************@microsof t.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]
- mv*@spam.guard.caspershouse.com

"not_a_commie" <no********@gmail.comwrote in message
news:11**********************@o80g2000hse.googlegr oups.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:
/// <summary>
/// Create an object of the given type
/// A default constructor is required to be successful.
/// A failure will return null.
/// </summary>
/// <param name="type">The type of the object to create.</param>
/// <param name="constructorParams">Arguments for the desired
constructor.</param>
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(CtorDelega te)))();
// we could cache these delegates with a type lookup
// but preparation time is really very minimal
// see here:
http://blogs.msdn.com/haibo_luo/arch...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();

Dec 13 '07 #3

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
>
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote
in message news:E7**********************************@microsof t.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]
- mv*@spam.guard.caspershouse.com

"not_a_commie" <no********@gmail.comwrote in message
news:11**********************@o80g2000hse.googleg roups.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:
/// <summary>
/// Create an object of the given type
/// A default constructor is required to be successful.
/// A failure will return null.
/// </summary>
/// <param name="type">The type of the object to create.</param>
/// <param name="constructorParams">Arguments for the desired
constructor.</param>
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(CtorDelega te)))();
// we could cache these delegates with a type lookup
// but preparation time is really very minimal
// see here:
http://blogs.msdn.com/haibo_luo/arch...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();


Dec 13 '07 #4
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<string,INamedctor = Expression.Lambda<Func<string,
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);
}
}
Dec 14 '07 #5
Refactored helper methods, to allow simple usage, i.e.

Type type = typeof(Demo); // however you get this!
var ctor = type.Ctor<string, INamed>();

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<string, object>

Marc

-----------

public static Func<TResultCtor<TResult>(this Type type) {
ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);

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

return Expression.Lambda<Func<TArg1, TResult>>(
Expression.New(ci, param1), param1).Compile();
}
public static Func<TArg1, TArg2, TResultCtor<TArg1, TArg2,
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<Func<TArg1, TArg2, TResult>>(
Expression.New(ci, param1, param2), param1,
param2).Compile();
}
public static Func<TArg1, TArg2, TArg3, TResultCtor<TArg1,
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<Func<TArg1, TArg2, TArg3, TResult>>(
Expression.New(ci, param1, param2, param3), param1,
param2, param3).Compile();
}
public static Func<TArg1, TArg2, TArg3, TArg4, TResult>
Ctor<TArg1, TArg2, TArg3, TArg4, TResult>(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<Func<TArg1, TArg2, TArg3, TArg4,
TResult>>(
Expression.New(ci, param1, param2, param3, param4),
param1, param2, param3, param4).Compile();
}
Dec 14 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Yodai | last post by:
Hi all... I am trying to construct an 2x14 array that compares a given character with the 1st column of data type "t" and returns the second column's appropriate value "v". I've been trying this,...
11
by: Ignacio X. Domínguez | last post by:
Hi. I'm developing a desktop application that needs to store some data in a local file. Let's say for example that I want to have an address book with names and phone numbers in a file. I would...
11
by: hoopsho | last post by:
Hi Everyone, I am trying to write a program that does a few things very fast and with efficient use of memory... a) I need to parse a space-delimited file that is really large, upwards fo a...
2
by: gangesmaster | last post by:
finally, i opened a wiki for Construct, the "parsing made fun" library. the project's page: http://pyconstruct.sourceforge.net/ the project's wiki: http://pyconstruct.wikispaces.com/ (anyone can...
3
by: _DD | last post by:
I had one experimented with binary serialization of an ArrayList of structs (each struct mostly contains strings). Strangely enough, it did not run as fast as custom XML storage (latter was...
3
by: Harry Haller | last post by:
What is the fastest way to search a client-side database? I have about 60-65 kb of data downloaded to the client which is present in 3 dynamically created list boxes. The boxes are filled from 3...
1
by: Harry Haller | last post by:
What is the fastest way to search a client-side database? I have about 60-65 kb of data downloaded to the client which is present in 3 dynamically created list boxes. The boxes are filled from 3...
5
by: Ramon F Herrera | last post by:
I was looking at some open source code, and found something that I had never seen before: const struct ast_datastore_info dialed_interface_info = { .type ="dialed-interface", .destroy =...
3
by: =?GB2312?B?0rvK18qr?= | last post by:
Hi all, Recently I asked a question on this group: I got these suggestion: 1) try construct
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.