Re: Speed improvement using compile time generate proxies

"Fabio Maulo" <[email protected]> Mon, 1 Sep 2008 09:26:47 -0300
Newsgroups gmane.comp.windows.dotnet.nhibernate.devel
Message-ID <[email protected]>
--===============0098346762==
Content-Type: multipart/alternative; 
	boundary="----=_Part_24411_27946154.1220272007350"

------=_Part_24411_27946154.1220272007350
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

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 familia=
r
> > 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 invoi=
ce
> >       }*
> > **
> > *      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 i=
n
> > 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 prox=
y
> > 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 typ=
e
> > 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, ne=
w
> > 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 tak=
e
> > 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 wor=
ld
> 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

------=_Part_24411_27946154.1220272007350
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

<div dir=3D"ltr">And please since NH have a proxyfactoryfactory and ByteCod=
eProvider try to create separate injectable implementation.<br>Then we can =
test it in the core and hopeful use the new implementation as default.<br>
<br><div class=3D"gmail_quote">2008/9/1 &quot;Andr=E9s G. Aragoneses&quot; =
<span dir=3D"ltr">&lt;<a href=3D"mailto:[email protected]">[email protected]<=
/a>&gt;</span><br><blockquote class=3D"gmail_quote" style=3D"border-left: 1=
px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"=
>
+1<br>
<br>
I&#39;ve had similar performance issues and I would vote for this to be<br>
included in NH Core vNext, so let&#39;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>
<font color=3D"#888888"><br>
 &nbsp; &nbsp; &nbsp; &nbsp;Andr=E9s<br>
</font><div><div></div><div class=3D"Wj3C7c"><br>
<br>
Johan Kirsten wrote:<br>
&gt; Greetings<br>
&gt;<br>
&gt; I recently had the opportunity to move a project onto NHibernate. The<=
br>
&gt; project was using Gentle.NET. After moving the project onto NHibernate=
,<br>
&gt; I noticed that the application had become slower. For those not famili=
ar<br>
&gt; with Gentle.NET, one of the biggest differences between Gentle.NET and=
<br>
&gt; NHibernate is the use of runtime generated proxies. Gentle.NET does no=
t<br>
&gt; make use of runtime generated proxies, but rather method calls.<br>
&gt;<br>
&gt; An example of an NHibernate objects would be:<br>
&gt;<br>
&gt; * &nbsp; public class Invoice {<br>
&gt; &nbsp; &nbsp; &nbsp; private int _id;<br>
&gt; &nbsp; &nbsp; &nbsp; private string _reference;<br>
&gt; &nbsp; &nbsp; &nbsp; private Company _company;<br>
&gt; &nbsp; &nbsp; &nbsp; private IList&lt;InvoiceItem&gt; _invoiceItems;*<=
br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public Invoice() {<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public int Id {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _id; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _id =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public virtual string Reference {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _reference; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _reference =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public virtual Company Company {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _company; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _company =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public virtual IList&lt;InvoiceItem&gt; InvoiceI=
tems {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _invoiceItems; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _invoiceItems =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt; **<br>
&gt; * &nbsp; public class Company {<br>
&gt; &nbsp; &nbsp; &nbsp; private int _id;<br>
&gt; &nbsp; &nbsp; &nbsp; private string _name;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public Company() {<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public int Id {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _id; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _id =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public string Name {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _name; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _name =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; The equivalent for Gentle.NET would be:<br>
&gt;<br>
&gt; * &nbsp; public class Invoice {<br>
&gt; &nbsp; &nbsp; &nbsp; private int _id;<br>
&gt; &nbsp; &nbsp; &nbsp; private string _reference;<br>
&gt; &nbsp; &nbsp; &nbsp; private int _companyKey;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public Invoice() {<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public int Id {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _id; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _id =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public virtual string Reference {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _reference; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _reference =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public int CompanyKey {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _companyKey; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _companyKey =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public Company GetCompany() {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Code that executes SQL and return=
 company for current invoice<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public static IList&lt;Invoice&gt; GetList() {<b=
r>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Code that executes SQL and return=
s all invoices<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt; **<br>
&gt; * &nbsp; public class Company {<br>
&gt; &nbsp; &nbsp; &nbsp; private int _id;<br>
&gt; &nbsp; &nbsp; &nbsp; private string _name;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public Company() {<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public int Id {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _id; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _id =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public string Name {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return _name; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { _name =3D value; }<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public IList&lt;Invoice&gt; GetInvoiceList() {<b=
r>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Code that executes SQL and return=
s invoices for current company<br>
&gt; &nbsp; &nbsp; &nbsp; }*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;public static IList&lt;Company&gt; GetList() {<b=
r>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Code that executes SQL and return=
s all companies<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; It is important to note that - in general and assuming lazy loading -<=
br>
&gt; Gentle.NET and NHibernate will execute the same SQL at the same point =
in<br>
&gt; code. For example the Gentle.NET code:<br>
&gt;<br>
&gt; * &nbsp; IList invoiceList =3D Invoice.GetList();<br>
&gt; &nbsp; &nbsp;foreach (Invoice invoice in invoiceList) {<br>
&gt; &nbsp; &nbsp; &nbsp; Company company =3D invoice.GetCompany();*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;// Print invoice and company information<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; will request a list of invoices and the company for each invoice.<br>
&gt; NHibernate will do the same:<br>
&gt;<br>
&gt; * &nbsp; IList invoiceList =3D InvoiceDAO.GetList();<br>
&gt; &nbsp; &nbsp;foreach (Invoice invoice in invoiceList) {<br>
&gt; &nbsp; &nbsp; &nbsp; Company company =3D invoice.Company;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp;// Print invoice and company information<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; What I found was that the Gentle.NET code was faster. The only<br>
&gt; difference was the runtime generated proxies.<br>
&gt;<br>
&gt; The point I am trying to make is NHibernate takes a performance hit<br=
>
&gt; because of runtime generated proxies. I investigated and realised that=
<br>
&gt; the queries that were taking the longest were those retrieving lists o=
f<br>
&gt; complex objects (objects containing other objects). These were the<br>
&gt; objects that used the most runtime generated proxies. I dived into the=
<br>
&gt; NHibernate code to understand why this is happening. What I discovered=
<br>
&gt; is that if you query a List of Invoices, NHibernate will compile a pro=
xy<br>
&gt; for each Company of each row.<br>
&gt;<br>
&gt; To make it clear, for the first row in an Invoice results set,<br>
&gt; NHibernate (using Castle&#39;s dynamic proxy) generates a Company prox=
y type<br>
&gt; and then instantiates the proxy. For the second row, NHibernate again<=
br>
&gt; generates a Company proxy type and then instantiates the proxy.<br>
&gt; Therefore for a 100 invoices the same Company proxy type will be<br>
&gt; generated 100 times. After investigation I confirmed that this holds<b=
r>
&gt; true for NH 1.2.1 and 2.0, although I suspect that NH 2.0 does not<br>
&gt; suffer as much due to optimization in Castle&#39;s new dynamic proxy.<=
br>
&gt;<br>
&gt; 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>
&gt; code of NHibernate.Proxy.CastleProxyFactory, which is responsible for<=
br>
&gt; proxy generation. I had it store the type on its first pass and then t=
o<br>
&gt; use the stored type to instantiate each instance. I added the data mem=
ber:<br>
&gt;<br>
&gt; * &nbsp; private System.Type _proxyType;*<br>
&gt;<br>
&gt; And altered the GetProxy method from:<br>
&gt;<br>
&gt; * &nbsp; public INHibernateProxy GetProxy(object id, ISessionImplement=
or<br>
&gt; session) {<br>
&gt; &nbsp; &nbsp; &nbsp; try {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CastleLazyInitializer initializer =
=3D new<br>
&gt; CastleLazyInitializer(_persistentClass, id, _getIdentifierMethod,<br>
&gt; _setIdentifierMethod, session);*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; object generatedProxy =3D null;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; if (IsClassProxy) {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generatedProxy =3D<br>
&gt; _proxyGenerator.CreateClassProxy(_persistentClass, _interfaces,<br>
&gt; initializer, false);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; generatedProxy =3D _proxyGen=
erator.CreateProxy(_interfaces,<br>
&gt; initializer, new object());<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; initializer._constructed =3D true;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (INHibernateProxy)generatedPr=
oxy;<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp; &nbsp; catch (Exception e) {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.Error(&quot;Creating a proxy ins=
tance failed&quot;, e);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new HibernateException(&quot;C=
reating a proxy instance<br>
&gt; failed&quot;, e);<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; to:<br>
&gt;<br>
&gt; * &nbsp; public INHibernateProxy GetProxy(object id, ISessionImplement=
or<br>
&gt; session) {<br>
&gt; &nbsp; &nbsp; &nbsp; try {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CastleLazyInitializer initializer =
=3D new<br>
&gt; CastleLazyInitializer(_persistentClass, id, _getIdentifierMethod,<br>
&gt; _setIdentifierMethod, session);*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; object generatedProxy =3D null;*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; if (IsClassProxy) {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (_proxyType =3D=3D null)<=
br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_proxyType =3D<=
br>
&gt; _proxyGenerator.ProxyBuilder.CreateClassProxy(_persistentClass,<br>
&gt; _interfaces);*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;generatedProxy =3D Activato=
r.CreateInstance(_proxyType,<br>
&gt; initializer);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (_proxyType =3D=3D null)<=
br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_proxyType =3D<=
br>
&gt; _proxyGenerator.ProxyBuilder.CreateInterfaceProxy(_interfaces,<br>
&gt; typeof(object));*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;generatedProxy =3D Activato=
r.CreateInstance(_proxyType, new<br>
&gt; object[] { initializer, new object() });<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}*<br>
&gt; **<br>
&gt; * &nbsp; &nbsp; &nbsp; &nbsp; initializer._constructed =3D true;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (INHibernateProxy)generatedPr=
oxy;<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp; &nbsp; catch (Exception e) {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.Error(&quot;Creating a proxy ins=
tance failed&quot;, e);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new HibernateException(&quot;C=
reating a proxy instance<br>
&gt; failed&quot;, e);<br>
&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp;}*<br>
&gt;<br>
&gt; This provided a speed improvement, but this isn&#39;t a solution. I do=
 not<br>
&gt; want any delays at runtime due to proxy generation. I wanted to<br>
&gt; translate all of the types at startup. But for a lot of classes this<b=
r>
&gt; would take too long and use too much memory. Then I found compile time=
<br>
&gt; generated proxies and it fit perfectly. Check out<br>
&gt; <a href=3D"http://code.google.com/p/nhibernateproxygenerator/" target=
=3D"_blank">http://code.google.com/p/nhibernateproxygenerator/</a> by WC Pi=
erce. I<br>
&gt; downloaded the source code and altered it to compile multiple librarie=
s<br>
&gt; (my domain is spread over multiple libraries). The library it generate=
d<br>
&gt; contains a ProxyFactoryFactory which you can use by setting the<br>
&gt; &quot;proxyfactory.factory_class&quot; property in your config file:<b=
r>
&gt;<br>
&gt; * &nbsp; &nbsp; &nbsp;&lt;property<br>
&gt; name=3D&quot;proxyfactory.factory_class&quot;&gt;StaticProxyFactoryFac=
tory,<br>
&gt; Library.Proxies&lt;/property&gt;*<br>
&gt;<br>
&gt; It worked amazingly well. The speed improved significantly. It does ta=
ke<br>
&gt; a while to compile the proxies. Especially if you have a lot of classe=
s.<br>
&gt; So I only plan to do this on deployment. I will continue to use runtim=
e<br>
&gt; generated proxies in my debug environment. This solution seems to work=
<br>
&gt; very well. Please provide any thoughts and comments. I am especially<b=
r>
&gt; interested in hearing any comments from people that can point out any<=
br>
&gt; serious downside to this approach. Are there specific reasons why<br>
&gt; runtime generated proxies are prefered over compile time generated<br>
&gt; proxies that I am not aware of?<br>
&gt;<br>
&gt; Finally I want to state that I hope that the NHibernate community will=
<br>
&gt; contemplate making compile time proxy generation a standard feature in=
<br>
&gt; the next release of NHibernate.<br>
&gt;<br>
&gt; Thanks<br>
&gt;<br>
&gt; Johan Kirsten<br>
&gt;<br>
&gt;<br>
</div></div>&gt; ----------------------------------------------------------=
--------------<br>
<div><div></div><div class=3D"Wj3C7c">&gt;<br>
&gt; ----------------------------------------------------------------------=
---<br>
&gt; This SF.Net email is sponsored by the Moblin Your Move Developer&#39;s=
 challenge<br>
&gt; Build the coolest Linux based applications with Moblin SDK &amp; win g=
reat prizes<br>
&gt; Grand prize is a trip for two to an Open Source event anywhere in the =
world<br>
&gt; <a href=3D"http://moblin-contest.org/redirect.php?banner_id=3D100&amp;=
url=3D/" target=3D"_blank">http://moblin-contest.org/redirect.php?banner_id=
=3D100&amp;url=3D/</a><br>
&gt;<br>
&gt;<br>
&gt; ----------------------------------------------------------------------=
--<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Nhibernate-development mailing list<br>
&gt; <a href=3D"mailto:[email protected]">Nhiber=
[email protected]</a><br>
&gt; <a href=3D"https://lists.sourceforge.net/lists/listinfo/nhibernate-dev=
elopment" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/nh=
ibernate-development</a><br>
<br>
<br>
-------------------------------------------------------------------------<b=
r>
This SF.Net email is sponsored by the Moblin Your Move Developer&#39;s chal=
lenge<br>
Build the coolest Linux based applications with Moblin SDK &amp; 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&amp;url=
=3D/" target=3D"_blank">http://moblin-contest.org/redirect.php?banner_id=3D=
100&amp;url=3D/</a><br>
_______________________________________________<br>
Nhibernate-development mailing list<br>
<a href=3D"mailto:[email protected]">Nhibernate-=
[email protected]</a><br>
<a href=3D"https://lists.sourceforge.net/lists/listinfo/nhibernate-developm=
ent" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/nhibern=
ate-development</a><br>
</div></div></blockquote></div><br><br clear=3D"all"><br>-- <br>Fabio Maulo=
<br>
</div>

------=_Part_24411_27946154.1220272007350--


--===============0098346762==
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=/
--===============0098346762==
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

--===============0098346762==--