代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Cameron

在db40(.net)中处理大型集合

  •  3
  • Jeffrey Cameron  · 技术社区  · 16 年前

    using (var reader = new FileUnitReader(Settings, Dictionary, m_fileNameResolver, ObjectFactory.Resolve<DataValueConverter>(), ObjectFactory.Resolve<UnitFactory>()))
    using (var db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), path))
    {
        var timer = new Stopwatch();
        timer.Start();
        IUnit unit = reader.GetNextUnit();
        while (unit != null)
        {
            db.Store(unit);
            unit = reader.GetNextUnit();
        }
        timer.Stop()
        db.Close();
    
        var elapsed = timer.Elapsed;
    }
    

    在这种情况下,有人能提供关于如何提高性能的建议吗?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Gamlor Gabriele Ran    16 年前

    在这种情况下,我认为有几种方法可以提高性能。

    fast-reflector 为了你的案子。请注意,FastReflector会消耗更多内存。但是在你的场景中,这并不重要。你可以像这样使用快速反射器:

    var config = Db4oEmbedded.NewConfiguration();
    config.Common.ReflectWith(new FastNetReflector());
    
    using(var container = Db4oEmbedded.OpenFile(config, fileName))
    {
    }
    

    当我做类似的小型“基准测试”时,我发现更大的缓存大小也会略微提高性能,即使在写入数据库时也是如此:

    var config = Db4oEmbedded.NewConfiguration();
    config.File.Storage = new CachingStorage(new FileStorage(), 128, 1024 * 4);
    

    db4o的事务处理并没有真正针对大型事务进行优化。在一个事务中存储100万个对象时,提交可能需要很长时间,或者内存不足。因此,您可能希望更频繁地提交。例如,在每存储100000个对象之后提交。当然,您需要检查它是否真的对您的场景产生了影响。

        2
  •  1
  •   Carl Rosenberger    16 年前

    通过在OpenFile()调用中添加.Ext()来获取扩展接口。

    在存储完所有对象后清除它。

    using (var db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), path).Ext())
    // ....
    db.Store(unit);
    db.Purge(unit);
    // ....
    

    如果您使用存储配置(即db4o以下的可插拔文件系统),那么您可能最有可能获得另一项重大改进。最新的8.0版本具有更好的缓存实现,在处理大量缓存页时,不会降低缓存维护的性能。

    config.File.Storage = new CachingStorage(new FileStorage(), 128, 1024 * 4);
    

    如果是这样,你也可以尝试更高的数字:

    config.File.Storage = new CachingStorage(new FileStorage(), 1280, 1024 * 40);