2010-12-02 21 views
3

私たちはモバイルアプリケーションを構築しており、NHibernate + Fluentを評価しています。問題は、初めてISessionFactoryを作成するときに、完全に2分かかります。テーブル構造は非常にシンプルです(3つのテーブル)。キャッシングFluent NHibernate ISessionFactory

それ以降の呼び出しはすべて非常に高速です。

私がしたいのは、アプリケーションの再起動の間にISessionFactoryをキャッシュするか、何とか最初にその作成をスピードアップすることです。

キャッシュ可能かどうかについてのアイデアはありますか?すべての私の読書から、あまりスピードアップしていない。

答えて

0

NHibernateはコンフィグレーションとISessionFactoryを構築するときに、コンフィグレーションとマッピングを解析してランタイムデータ構造を構築します。 (これは、EFとLINQ-to-SQLにも当てはまりますが、コンテキスト内では隠されていますが)2分は非常に長いように見えますが、このコストを排除する方法はあまりありません。このコードをタイミング:

 var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     var cfg = new Configuration(); 
     cfg.Configure(); 
     var sessionFactory = cfg.BuildSessionFactory(); 
     stopwatch.Stop(); 
     Console.WriteLine("Startup time was " + stopwatch.ElapsedMilliseconds + "ms"); 

これは、デモプロジェクトだと唯一のいくつかのクラスとのマッピングを持っていますが、それは、添付のデバッガなし〜850ミリ秒を要しました。デバッガを接続すると、約2秒かかりました。

アプリをプロファイリングして2分を費やしている場所を確認しましたか?

+0

ええ、私たちはこれをやっています。それは、その特定のアイテムのためにとても長い時間をどのように発見したかです。わかりやすくするために、非モバイルエミュレータ(Windowsマシンのような)でこれを行うには数ミリ秒かかります。それはちょうどデバイス上のものです(そして、エミュレータはとても遅いです)。 –

+0

私は、モバイルデバイスでNHibernateを実行しようとしたことはありません。たぶん、プロセッサの低速化、メモリサイズの縮小、実行時間の短縮などがあります。 (私はあなたが.NET Compact Framework上で動作していると仮定しています)。フィールの提唱している設定のシリアル化についての提案は、検討する価値があると思います。 –

2

ISessionFactoryを静的変数(VB用の共有)として定義し、アプリケーションの起動時に一度だけインスタンス化するのは、Webアプリケーションがこの問題を回避する方法です。私は、これはメモリ効率の要求とモバイルアプリのための課題を提起するかもしれませんが、モバイルプラットフォームに応じて、あなたは1を恐れるだろうほど短くないかもしれないアプリケーションの寿命を使用している実感 ...

public class NHHelper { 
     private static string _connectionString; 
     private static ISessionFactory _sessionFactory; 

     private static ISessionFactory SessionFactory { 
      get { 
       if (_sessionFactory == null) { 
          _sessionFactory = Fluently.Configure() 
           .Database(MsSqlConfiguration.MsSql2008.ShowSql() 
            .ConnectionString(p => p.Is(_connectionString))) 
           .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(NHHelper)))) 
           .BuildSessionFactory(); 
       } 
       return _sessionFactory; 
      } 
     } 

// this is called once upon application startup... 
     public static void WarmUpSessionFactory(string connectionString) { 
      _connectionString = connectionString; 
      var factory = SessionFactory; 
     } 
// this is what you call to get a session for normal usage 
     public static ISession OpenSession() { 
      return SessionFactory.OpenSession(); 
     } 
    } 
+0

私の問題は、アプリケーションインスタンス内で永続化されているセッションファクトリではなく、遅くなるアプリケーションインスタンス間です。したがって、これは本当に私を助けません。代わりにキャッシュを試しています。 –

4

することができます設定をシリアライズして保存し、2回目にその設定をロードして、作成にかかる時間を短縮します。あなたが変更を加えたら、古い設定を吹き飛ばして新しいバージョンをシリアル化する必要があります。そうしないと、古い設定がロードされます。

私はこれを行うためのコードを覚えていない、例を掘り下げようとします。

編集:このビデオでは http://vimeo.com/16225792

Ayendeで約24分では、コンフィギュレーションシリアル化について説明します。

+4

良いアイデアですが、configを解析して3つのテーブル/エンティティ用のセッションファクトリを構築するのに2分はとんでもなく長いようです。私はここに何か他のものがあると思います。これは最初に整理されてから、設定のシリアル化を使ってアプリケーションを複雑にする必要があります。 –

+0

はい、おそらく彼はアプリケーションの残りの部分と同じアセンブリで彼のマッピングを持っていることに同意します。 – Phill

+0

ここにいくつかの例がありますhttp://weblogs.asp.net/ricardoperes/archive/2010/03/31/speeding-up-nhibernate-startup-time.aspxしかし、はい、それは一般に何百ものエンティティ。 –