Re: Speed improvement using compile timegenerate proxies
"Jon Palmer" <[email protected]> Mon, 1 Sep 2008 12:33:53 -0400
| Newsgroups | gmane.comp.windows.dotnet.nhibernate.devel |
|---|---|
| Message-ID | <8EE6E8CD12C62F4A99424FC34C543D75C7DC84@shrapnel.cn.contactnetworks.com> |
This is a multi-part message in MIME format. --===============1042934962== Content-class: urn:content-classes:message Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C90C50.22F350EF" This is a multi-part message in MIME format. ------_=_NextPart_001_01C90C50.22F350EF Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable What kind of performance improvements are we talking about? Can you = provide some hard numbers? =20 From: [email protected] = [mailto:[email protected]] On Behalf = Of Fabio Maulo Sent: Monday, September 01, 2008 5:27 AM To: the NHibernate development list Subject: Re: [NHibernate-development] Speed improvement using compile = timegenerate proxies =20 And please since NH have a proxyfactoryfactory and ByteCodeProvider try = to create separate injectable implementation. Then we can test it in the core and hopeful use the new implementation = as default. 2008/9/1 "Andr=E9s G. Aragoneses" <[email protected]> +1 I've had similar performance issues and I would vote for this to be included in NH Core vNext, so let's start creating a JIRA issue for it, right? Johan, wonderful research! Do you have rough benchmark numbers about the performance increase? A simple percentage number? Regards, Andr=E9s Johan Kirsten wrote: > Greetings > > I recently had the opportunity to move a project onto NHibernate. The > project was using Gentle.NET. After moving the project onto = NHibernate, > I noticed that the application had become slower. For those not = familiar > with Gentle.NET, one of the biggest differences between Gentle.NET and > NHibernate is the use of runtime generated proxies. Gentle.NET does = not > make use of runtime generated proxies, but rather method calls. > > An example of an NHibernate objects would be: > > * public class Invoice { > private int _id; > private string _reference; > private Company _company; > private IList<InvoiceItem> _invoiceItems;* > ** > * public Invoice() { > }* > ** > * public int Id { > get { return _id; } > set { _id =3D value; } > }* > ** > * public virtual string Reference { > get { return _reference; } > set { _reference =3D value; } > }* > ** > * public virtual Company Company { > get { return _company; } > set { _company =3D value; } > }* > ** > * public virtual IList<InvoiceItem> InvoiceItems { > get { return _invoiceItems; } > set { _invoiceItems =3D value; } > } > }* > ** > * public class Company { > private int _id; > private string _name;* > ** > * public Company() { > }* > ** > * public int Id { > get { return _id; } > set { _id =3D value; } > }* > ** > * public string Name { > get { return _name; } > set { _name =3D value; } > } > }* > > The equivalent for Gentle.NET would be: > > * public class Invoice { > private int _id; > private string _reference; > private int _companyKey;* > ** > * public Invoice() { > }* > ** > * public int Id { > get { return _id; } > set { _id =3D value; } > }* > ** > * public virtual string Reference { > get { return _reference; } > set { _reference =3D value; } > }* > ** > * public int CompanyKey { > get { return _companyKey; } > set { _companyKey =3D value; } > }* > ** > * public Company GetCompany() { > // Code that executes SQL and return company for current = invoice > }* > ** > * public static IList<Invoice> GetList() { > // Code that executes SQL and returns all invoices > } > }* > ** > * public class Company { > private int _id; > private string _name;* > ** > * public Company() { > }* > ** > * public int Id { > get { return _id; } > set { _id =3D value; } > }* > ** > * public string Name { > get { return _name; } > set { _name =3D value; } > }* > ** > * public IList<Invoice> GetInvoiceList() { > // Code that executes SQL and returns invoices for current = company > }* > ** > * public static IList<Company> GetList() { > // Code that executes SQL and returns all companies > } > }* > > It is important to note that - in general and assuming lazy loading - > Gentle.NET and NHibernate will execute the same SQL at the same point = in > code. For example the Gentle.NET code: > > * IList invoiceList =3D Invoice.GetList(); > foreach (Invoice invoice in invoiceList) { > Company company =3D invoice.GetCompany();* > ** > * // Print invoice and company information > }* > > will request a list of invoices and the company for each invoice. > NHibernate will do the same: > > * IList invoiceList =3D InvoiceDAO.GetList(); > foreach (Invoice invoice in invoiceList) { > Company company =3D invoice.Company;* > ** > * // Print invoice and company information > }* > > What I found was that the Gentle.NET code was faster. The only > difference was the runtime generated proxies. > > The point I am trying to make is NHibernate takes a performance hit > because of runtime generated proxies. I investigated and realised that > the queries that were taking the longest were those retrieving lists = of > complex objects (objects containing other objects). These were the > objects that used the most runtime generated proxies. I dived into the > NHibernate code to understand why this is happening. What I discovered > is that if you query a List of Invoices, NHibernate will compile a = proxy > for each Company of each row. > > To make it clear, for the first row in an Invoice results set, > NHibernate (using Castle's dynamic proxy) generates a Company proxy = type > and then instantiates the proxy. For the second row, NHibernate again > generates a Company proxy type and then instantiates the proxy. > Therefore for a 100 invoices the same Company proxy type will be > generated 100 times. After investigation I confirmed that this holds > true for NH 1.2.1 and 2.0, although I suspect that NH 2.0 does not > suffer as much due to optimization in Castle's new dynamic proxy. > > To confirm my suspisions I experimented with NH 1.2.1. I altered the > code of NHibernate.Proxy.CastleProxyFactory, which is responsible for > proxy generation. I had it store the type on its first pass and then = to > use the stored type to instantiate each instance. I added the data = member: > > * private System.Type _proxyType;* > > And altered the GetProxy method from: > > * public INHibernateProxy GetProxy(object id, ISessionImplementor > session) { > try { > CastleLazyInitializer initializer =3D new > CastleLazyInitializer(_persistentClass, id, _getIdentifierMethod, > _setIdentifierMethod, session);* > ** > * object generatedProxy =3D null;* > ** > * if (IsClassProxy) { > generatedProxy =3D > _proxyGenerator.CreateClassProxy(_persistentClass, _interfaces, > initializer, false); > } > else { > generatedProxy =3D = _proxyGenerator.CreateProxy(_interfaces, > initializer, new object()); > }* > ** > * initializer._constructed =3D true; > return (INHibernateProxy)generatedProxy; > } > catch (Exception e) { > log.Error("Creating a proxy instance failed", e); > throw new HibernateException("Creating a proxy instance > failed", e); > } > }* > > to: > > * public INHibernateProxy GetProxy(object id, ISessionImplementor > session) { > try { > CastleLazyInitializer initializer =3D new > CastleLazyInitializer(_persistentClass, id, _getIdentifierMethod, > _setIdentifierMethod, session);* > ** > * object generatedProxy =3D null;* > ** > * if (IsClassProxy) { > if (_proxyType =3D=3D null) > _proxyType =3D > _proxyGenerator.ProxyBuilder.CreateClassProxy(_persistentClass, > _interfaces);* > ** > * generatedProxy =3D Activator.CreateInstance(_proxyType, > initializer); > } > else { > if (_proxyType =3D=3D null) > _proxyType =3D > _proxyGenerator.ProxyBuilder.CreateInterfaceProxy(_interfaces, > typeof(object));* > ** > * generatedProxy =3D Activator.CreateInstance(_proxyType, = new > object[] { initializer, new object() }); > }* > ** > * initializer._constructed =3D true; > return (INHibernateProxy)generatedProxy; > } > catch (Exception e) { > log.Error("Creating a proxy instance failed", e); > throw new HibernateException("Creating a proxy instance > failed", e); > } > }* > > This provided a speed improvement, but this isn't a solution. I do not > want any delays at runtime due to proxy generation. I wanted to > translate all of the types at startup. But for a lot of classes this > would take too long and use too much memory. Then I found compile time > generated proxies and it fit perfectly. Check out > http://code.google.com/p/nhibernateproxygenerator/ by WC Pierce. I > downloaded the source code and altered it to compile multiple = libraries > (my domain is spread over multiple libraries). The library it = generated > contains a ProxyFactoryFactory which you can use by setting the > "proxyfactory.factory_class" property in your config file: > > * <property > name=3D"proxyfactory.factory_class">StaticProxyFactoryFactory, > Library.Proxies</property>* > > It worked amazingly well. The speed improved significantly. It does = take > a while to compile the proxies. Especially if you have a lot of = classes. > So I only plan to do this on deployment. I will continue to use = runtime > generated proxies in my debug environment. This solution seems to work > very well. Please provide any thoughts and comments. I am especially > interested in hearing any comments from people that can point out any > serious downside to this approach. Are there specific reasons why > runtime generated proxies are prefered over compile time generated > proxies that I am not aware of? > > Finally I want to state that I hope that the NHibernate community will > contemplate making compile time proxy generation a standard feature in > the next release of NHibernate. > > Thanks > > Johan Kirsten > > > = ------------------------------------------------------------------------ > > = -------------------------------------------------------------------------= > This SF.Net email is sponsored by the Moblin Your Move Developer's = challenge > Build the coolest Linux based applications with Moblin SDK & win great = prizes > Grand prize is a trip for two to an Open Source event anywhere in the = world > http://moblin-contest.org/redirect.php?banner_id=3D100&url=3D/ > > > = ------------------------------------------------------------------------ > > _______________________________________________ > Nhibernate-development mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/nhibernate-development -------------------------------------------------------------------------= This SF.Net email is sponsored by the Moblin Your Move Developer's = challenge Build the coolest Linux based applications with Moblin SDK & win great = prizes Grand prize is a trip for two to an Open Source event anywhere in the = world http://moblin-contest.org/redirect.php?banner_id=3D100&url=3D/ _______________________________________________ Nhibernate-development mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nhibernate-development --=20 Fabio Maulo ------_=_NextPart_001_01C90C50.22F350EF Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = charset=3Diso-8859-1"> <html xmlns:v=3D"urn:schemas-microsoft-com:vml" = xmlns:o=3D"urn:schemas-microsoft-com:office:office" = xmlns:w=3D"urn:schemas-microsoft-com:office:word" = xmlns:x=3D"urn:schemas-microsoft-com:office:excel" = xmlns:p=3D"urn:schemas-microsoft-com:office:powerpoint" = xmlns:a=3D"urn:schemas-microsoft-com:office:access" = xmlns:dt=3D"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" = xmlns:s=3D"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" = xmlns:rs=3D"urn:schemas-microsoft-com:rowset" xmlns:z=3D"#RowsetSchema" = xmlns:b=3D"urn:schemas-microsoft-com:office:publisher" = xmlns:ss=3D"urn:schemas-microsoft-com:office:spreadsheet" = xmlns:c=3D"urn:schemas-microsoft-com:office:component:spreadsheet" = xmlns:odc=3D"urn:schemas-microsoft-com:office:odc" = xmlns:oa=3D"urn:schemas-microsoft-com:office:activation" = xmlns:html=3D"http://www.w3.org/TR/REC-html40" = xmlns:q=3D"http://schemas.xmlsoap.org/soap/envelope/" xmlns:D=3D"DAV:" = xmlns:x2=3D"http://schemas.microsoft.com/office/excel/2003/xml" = xmlns:ois=3D"http://schemas.microsoft.com/sharepoint/soap/ois/" = xmlns:dir=3D"http://schemas.microsoft.com/sharepoint/soap/directory/" = xmlns:ds=3D"http://www.w3.org/2000/09/xmldsig#" = xmlns:dsp=3D"http://schemas.microsoft.com/sharepoint/dsp" = xmlns:udc=3D"http://schemas.microsoft.com/data/udc" = xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema" = xmlns:sub=3D"http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/"= xmlns:ec=3D"http://www.w3.org/2001/04/xmlenc#" = xmlns:sp=3D"http://schemas.microsoft.com/sharepoint/" = xmlns:sps=3D"http://schemas.microsoft.com/sharepoint/soap/" = xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance" = xmlns:udcxf=3D"http://schemas.microsoft.com/data/udc/xmlfile" = xmlns:wf=3D"http://schemas.microsoft.com/sharepoint/soap/workflow/" = xmlns:mver=3D"http://schemas.openxmlformats.org/markup-compatibility/2006= " xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" = xmlns:mrels=3D"http://schemas.openxmlformats.org/package/2006/relationshi= ps" = xmlns:ex12t=3D"http://schemas.microsoft.com/exchange/services/2006/types"= = xmlns:ex12m=3D"http://schemas.microsoft.com/exchange/services/2006/messag= es" xmlns:Z=3D"urn:schemas-microsoft-com:" xmlns:st=3D"" = xmlns=3D"http://www.w3.org/TR/REC-html40"> <head> <meta name=3DGenerator content=3D"Microsoft Word 12 (filtered medium)"> <style> <!-- /* Font Definitions */ @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} @font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0in; margin-bottom:.0001pt; font-size:12.0pt; font-family:"Times New Roman","serif";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;} span.EmailStyle17 {mso-style-type:personal-reply; font-family:"Calibri","sans-serif"; color:#1F497D;} .MsoChpDefault {mso-style-type:export-only;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in;} div.Section1 {page:Section1;} --> </style> <!--[if gte mso 9]><xml> <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" /> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext=3D"edit"> <o:idmap v:ext=3D"edit" data=3D"1" /> </o:shapelayout></xml><![endif]--> </head> <body lang=3DEN-US link=3Dblue vlink=3Dpurple> <div class=3DSection1> <p class=3DMsoNormal><span = style=3D'font-size:11.0pt;font-family:"Calibri","sans-serif"; color:#1F497D'>What kind of performance improvements are we talking = about? Can you provide some hard numbers?<o:p></o:p></span></p> <p class=3DMsoNormal><span = style=3D'font-size:11.0pt;font-family:"Calibri","sans-serif"; color:#1F497D'><o:p> </o:p></span></p> <div style=3D'border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt = 0in 0in 0in'> <p class=3DMsoNormal><b><span = style=3D'font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span>= </b><span style=3D'font-size:10.0pt;font-family:"Tahoma","sans-serif"'> [email protected] [mailto:[email protected]] <b>On = Behalf Of </b>Fabio Maulo<br> <b>Sent:</b> Monday, September 01, 2008 5:27 AM<br> <b>To:</b> the NHibernate development list<br> <b>Subject:</b> Re: [NHibernate-development] Speed improvement using = compile timegenerate proxies<o:p></o:p></span></p> </div> <p class=3DMsoNormal><o:p> </o:p></p> <div> <p class=3DMsoNormal style=3D'margin-bottom:12.0pt'>And please since NH = have a proxyfactoryfactory and ByteCodeProvider try to create separate = injectable implementation.<br> Then we can test it in the core and hopeful use the new implementation = as default.<o:p></o:p></p> <div> <p class=3DMsoNormal>2008/9/1 "Andr=E9s G. Aragoneses" <<a href=3D"mailto:[email protected]">[email protected]</a>><o:p></o:p></p> <p class=3DMsoNormal>+1<br> <br> I've had similar performance issues and I would vote for this to be<br> included in NH Core vNext, so let's start creating a JIRA issue for = it,<br> right?<br> <br> Johan, wonderful research! Do you have rough benchmark numbers about = the<br> performance increase? A simple percentage number?<br> <br> Regards,<br> <span style=3D'color:#888888'><br> Andr=E9s</span><o:p></o:p></p> <div> <div> <p class=3DMsoNormal><br> <br> Johan Kirsten wrote:<br> > Greetings<br> ><br> > I recently had the opportunity to move a project onto NHibernate. = The<br> > project was using Gentle.NET. After moving the project onto = NHibernate,<br> > I noticed that the application had become slower. For those not = familiar<br> > with Gentle.NET, one of the biggest differences between Gentle.NET = and<br> > NHibernate is the use of runtime generated proxies. Gentle.NET does = not<br> > make use of runtime generated proxies, but rather method calls.<br> ><br> > An example of an NHibernate objects would be:<br> ><br> > * public class Invoice {<br> > private int _id;<br> > private string _reference;<br> > private Company _company;<br> > private IList<InvoiceItem> = _invoiceItems;*<br> > **<br> > * public Invoice() {<br> > }*<br> > **<br> > * public int Id {<br> > get { return _id; }<br> > set { _id =3D value; }<br> > }*<br> > **<br> > * public virtual string Reference {<br> > get { return _reference; }<br> > set { _reference =3D value; }<br> > }*<br> > **<br> > * public virtual Company Company {<br> > get { return _company; }<br> > set { _company =3D value; }<br> > }*<br> > **<br> > * public virtual IList<InvoiceItem> = InvoiceItems {<br> > get { return _invoiceItems; }<br> > set { _invoiceItems =3D value; = }<br> > }<br> > }*<br> > **<br> > * public class Company {<br> > private int _id;<br> > private string _name;*<br> > **<br> > * public Company() {<br> > }*<br> > **<br> > * public int Id {<br> > get { return _id; }<br> > set { _id =3D value; }<br> > }*<br> > **<br> > * public string Name {<br> > get { return _name; }<br> > set { _name =3D value; }<br> > }<br> > }*<br> ><br> > The equivalent for Gentle.NET would be:<br> ><br> > * public class Invoice {<br> > private int _id;<br> > private string _reference;<br> > private int _companyKey;*<br> > **<br> > * public Invoice() {<br> > }*<br> > **<br> > * public int Id {<br> > get { return _id; }<br> > set { _id =3D value; }<br> > }*<br> > **<br> > * public virtual string Reference {<br> > get { return _reference; }<br> > set { _reference =3D value; }<br> > }*<br> > **<br> > * public int CompanyKey {<br> > get { return _companyKey; }<br> > set { _companyKey =3D value; = }<br> > }*<br> > **<br> > * public Company GetCompany() {<br> > // Code that executes SQL and = return company for current invoice<br> > }*<br> > **<br> > * public static IList<Invoice> GetList() = {<br> > // Code that executes SQL and = returns all invoices<br> > }<br> > }*<br> > **<br> > * public class Company {<br> > private int _id;<br> > private string _name;*<br> > **<br> > * public Company() {<br> > }*<br> > **<br> > * public int Id {<br> > get { return _id; }<br> > set { _id =3D value; }<br> > }*<br> > **<br> > * public string Name {<br> > get { return _name; }<br> > set { _name =3D value; }<br> > }*<br> > **<br> > * public IList<Invoice> GetInvoiceList() = {<br> > // Code that executes SQL and = returns invoices for current company<br> > }*<br> > **<br> > * public static IList<Company> GetList() = {<br> > // Code that executes SQL and = returns all companies<br> > }<br> > }*<br> ><br> > It is important to note that - in general and assuming lazy loading = -<br> > Gentle.NET and NHibernate will execute the same SQL at the same = point in<br> > code. For example the Gentle.NET code:<br> ><br> > * IList invoiceList =3D Invoice.GetList();<br> > foreach (Invoice invoice in invoiceList) {<br> > Company company =3D invoice.GetCompany();*<br> > **<br> > * // Print invoice and company information<br> > }*<br> ><br> > will request a list of invoices and the company for each = invoice.<br> > NHibernate will do the same:<br> ><br> > * IList invoiceList =3D InvoiceDAO.GetList();<br> > foreach (Invoice invoice in invoiceList) {<br> > Company company =3D invoice.Company;*<br> > **<br> > * // Print invoice and company information<br> > }*<br> ><br> > What I found was that the Gentle.NET code was faster. The only<br> > difference was the runtime generated proxies.<br> ><br> > The point I am trying to make is NHibernate takes a performance = hit<br> > because of runtime generated proxies. I investigated and realised = that<br> > the queries that were taking the longest were those retrieving = lists of<br> > complex objects (objects containing other objects). These were = the<br> > objects that used the most runtime generated proxies. I dived into = the<br> > NHibernate code to understand why this is happening. What I = discovered<br> > is that if you query a List of Invoices, NHibernate will compile a = proxy<br> > for each Company of each row.<br> ><br> > To make it clear, for the first row in an Invoice results set,<br> > NHibernate (using Castle's dynamic proxy) generates a Company proxy = type<br> > and then instantiates the proxy. For the second row, NHibernate = again<br> > generates a Company proxy type and then instantiates the proxy.<br> > Therefore for a 100 invoices the same Company proxy type will = be<br> > generated 100 times. After investigation I confirmed that this = holds<br> > true for NH 1.2.1 and 2.0, although I suspect that NH 2.0 does = not<br> > suffer as much due to optimization in Castle's new dynamic = proxy.<br> ><br> > To confirm my suspisions I experimented with NH <a = href=3D"http://1.2.1." target=3D"_blank">1.2.1.</a> I altered the<br> > code of NHibernate.Proxy.CastleProxyFactory, which is responsible = for<br> > proxy generation. I had it store the type on its first pass and = then to<br> > use the stored type to instantiate each instance. I added the data = member:<br> ><br> > * private System.Type _proxyType;*<br> ><br> > And altered the GetProxy method from:<br> ><br> > * public INHibernateProxy GetProxy(object id, = ISessionImplementor<br> > session) {<br> > try {<br> > CastleLazyInitializer initializer = =3D new<br> > CastleLazyInitializer(_persistentClass, id, = _getIdentifierMethod,<br> > _setIdentifierMethod, session);*<br> > **<br> > * object generatedProxy =3D null;*<br> > **<br> > * if (IsClassProxy) {<br> > generatedProxy =3D<br> > _proxyGenerator.CreateClassProxy(_persistentClass, _interfaces,<br> > initializer, false);<br> > }<br> > else {<br> > generatedProxy =3D _proxyGenerator.CreateProxy(_interfaces,<br> > initializer, new object());<br> > }*<br> > **<br> > * initializer._constructed =3D = true;<br> > return = (INHibernateProxy)generatedProxy;<br> > }<br> > catch (Exception e) {<br> > log.Error("Creating a proxy instance failed", e);<br> > throw new HibernateException("Creating a proxy instance<br> > failed", e);<br> > }<br> > }*<br> ><br> > to:<br> ><br> > * public INHibernateProxy GetProxy(object id, = ISessionImplementor<br> > session) {<br> > try {<br> > CastleLazyInitializer initializer = =3D new<br> > CastleLazyInitializer(_persistentClass, id, = _getIdentifierMethod,<br> > _setIdentifierMethod, session);*<br> > **<br> > * object generatedProxy =3D null;*<br> > **<br> > * if (IsClassProxy) {<br> > if (_proxyType =3D=3D = null)<br> > _proxyType = =3D<br> > _proxyGenerator.ProxyBuilder.CreateClassProxy(_persistentClass,<br> > _interfaces);*<br> > **<br> > * generatedProxy =3D Activator.CreateInstance(_proxyType,<br> > initializer);<br> > }<br> > else {<br> > if (_proxyType =3D=3D = null)<br> > _proxyType = =3D<br> > _proxyGenerator.ProxyBuilder.CreateInterfaceProxy(_interfaces,<br> > typeof(object));*<br> > **<br> > * generatedProxy =3D Activator.CreateInstance(_proxyType, new<br> > object[] { initializer, new object() });<br> > }*<br> > **<br> > * initializer._constructed =3D = true;<br> > return = (INHibernateProxy)generatedProxy;<br> > }<br> > catch (Exception e) {<br> > log.Error("Creating a proxy instance failed", e);<br> > throw new HibernateException("Creating a proxy instance<br> > failed", e);<br> > }<br> > }*<br> ><br> > This provided a speed improvement, but this isn't a solution. I do = not<br> > want any delays at runtime due to proxy generation. I wanted to<br> > translate all of the types at startup. But for a lot of classes = this<br> > would take too long and use too much memory. Then I found compile = time<br> > generated proxies and it fit perfectly. Check out<br> > <a href=3D"http://code.google.com/p/nhibernateproxygenerator/" target=3D"_blank">http://code.google.com/p/nhibernateproxygenerator/</a> = by WC Pierce. I<br> > downloaded the source code and altered it to compile multiple = libraries<br> > (my domain is spread over multiple libraries). The library it = generated<br> > contains a ProxyFactoryFactory which you can use by setting the<br> > "proxyfactory.factory_class" property in your config = file:<br> ><br> > * <property<br> > = name=3D"proxyfactory.factory_class">StaticProxyFactoryFactor= y,<br> > Library.Proxies</property>*<br> ><br> > It worked amazingly well. The speed improved significantly. It does = take<br> > a while to compile the proxies. Especially if you have a lot of = classes.<br> > So I only plan to do this on deployment. I will continue to use = runtime<br> > generated proxies in my debug environment. This solution seems to = work<br> > very well. Please provide any thoughts and comments. I am = especially<br> > interested in hearing any comments from people that can point out = any<br> > serious downside to this approach. Are there specific reasons = why<br> > runtime generated proxies are prefered over compile time = generated<br> > proxies that I am not aware of?<br> ><br> > Finally I want to state that I hope that the NHibernate community = will<br> > contemplate making compile time proxy generation a standard feature = in<br> > the next release of NHibernate.<br> ><br> > Thanks<br> ><br> > Johan Kirsten<br> ><br> ><o:p></o:p></p> </div> </div> <p class=3DMsoNormal>> ------------------------------------------------------------------------<= o:p></o:p></p> <div> <div> <p class=3DMsoNormal>><br> > = -------------------------------------------------------------------------= <br> > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge<br> > Build the coolest Linux based applications with Moblin SDK & = win great prizes<br> > Grand prize is a trip for two to an Open Source event anywhere in = the world<br> > <a = href=3D"http://moblin-contest.org/redirect.php?banner_id=3D100&url=3D= /" target=3D"_blank">http://moblin-contest.org/redirect.php?banner_id=3D100&= amp;url=3D/</a><br> ><br> ><br> > = ------------------------------------------------------------------------<= br> ><br> > _______________________________________________<br> > Nhibernate-development mailing list<br> > <a = href=3D"mailto:[email protected]">Nhibernate-d= [email protected]</a><br> > <a href=3D"https://lists.sourceforge.net/lists/listinfo/nhibernate-developme= nt" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/nhibernate= -development</a><br> <br> <br> -------------------------------------------------------------------------= <br> This SF.Net email is sponsored by the Moblin Your Move Developer's = challenge<br> Build the coolest Linux based applications with Moblin SDK & win = great prizes<br> Grand prize is a trip for two to an Open Source event anywhere in the = world<br> <a = href=3D"http://moblin-contest.org/redirect.php?banner_id=3D100&url=3D= /" target=3D"_blank">http://moblin-contest.org/redirect.php?banner_id=3D100&= amp;url=3D/</a><br> _______________________________________________<br> Nhibernate-development mailing list<br> <a = href=3D"mailto:[email protected]">Nhibernate-d= [email protected]</a><br> <a = href=3D"https://lists.sourceforge.net/lists/listinfo/nhibernate-developme= nt" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/nhibernate= -development</a><o:p></o:p></p> </div> </div> </div> <p class=3DMsoNormal><br> <br clear=3Dall> <br> -- <br> Fabio Maulo<o:p></o:p></p> </div> </div> </body> </html> ------_=_NextPart_001_01C90C50.22F350EF-- --===============1042934962== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ --===============1042934962== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Nhibernate-development mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nhibernate-development --===============1042934962==--