【问题标题】:Benchmark Linq2SQL, Subsonic2, Subsonic3 - Any other ideas to make them faster?Benchmark Linq2SQL、Subsonic 2、Subsonic 3 - 还有其他让它们更快的想法吗?
【发布时间】:2011-01-22 18:04:16
【问题描述】:

我与 Subsonic 2 合作已经 3 年多了...

在 Linq 出现,然后是 Subsonic 3 之后,我开始考虑转移到连接到 sql 的新 Linq 期货。

我必须说我开始使用 SubSonic 3 移动和移植我的 subsonic 2,很快我发现速度如此之慢以至于我不相信 - 并开始了所有测试。

然后我测试 Linq2Sql 并看到延迟 - 将其与 Subsonic 2 进行比较。

我的问题是,特别是对于 linq2sql 和即将推出的 dotnet 版本 4,我还能做些什么来加快它的速度? linq2sql 设置或类还有什么,而不是我用于我的问题的这段代码

我将我进行测试的项目以及结果的屏幕截图放在这里。

我如何进行测试 - 以及我的测量结果是否准确。

我只使用谷歌浏览器来回答我的问题,因为我很难在这里展示我用更复杂的程序完成的许多其他措施。这是最简单的一个,我只是测量Data Read。我怎么能证明这一点。我做了一个简单的 Thread.Sleep(10 seconds),看看我是否在 Google Chrome Measure 上看到了 10 秒,是的,我看到了。


(来源:planethost.gr

这里有更多关于这个 Sleep thead 的测试,看看 Chrome 实际提供了什么。

10 seconds delay
100 ms delay
Zero delay

只有 15 毫秒的小问题,与我不关心的其他测试相比,它是如此之小。

所以我衡量的是什么

我只测量通过每种方法读取的数据 - 没有计算数据或数据库延迟,或任何磁盘读取或类似的东西。稍后在带有结果的图像上,我显示度量上不存在磁盘活动
See this image to see what really I measure and if this is correct

我为什么选择这种测试

它很简单,它是真实的,它接近我真正的问题,我在真实数据的真实程序中发现了亚音速 3 的延迟。

现在让我们测试一下dals

Start by see this image 我对每个方法都有 4-5 次调用,一个接一个。

结果是。 对于一个 100 次的循环,请求 5 行,一个不存在,大约..

简单的 adonet:81ms
亚音速 2:210 毫秒
linq2sql:1.70 秒
linq2sql 使用 CompiledQuery.Compile :239ms
亚音速 3:15.00 秒(哇 - 极慢)

项目 http://www.planethost.gr/DalSpeedTests.rar


任何人都可以确认这个基准,或进行任何优化来帮助我吗?

其他测试

有人在此处发布此链接http://ormbattle.net/(然后将其删除-不知道为什么)在此页面中,您可以找到对所有人非常有用的高级测试,除了我在这里的亚音速 2 和亚音速 3 !

优化

我在这里真正要问的是,现在是否有人可以通过更改每个 dal 上的代码和设置来优化 DAL,而不是通过更改测试代码来优化 DAL。 比如……

优化 Linq2SQL

我开始搜索如何优化Linq2sql,发现 this article,也许还有更多。

最后,我使该页面中的技巧运行起来,并使用它们来优化代码。速度从 1.70 接近 1.50 秒.... 很大的改进,但仍然很慢。

然后我找到了different way - same idea article,哇!速度被炸飞了。 将这个技巧与 CompiledQuery.Compile 结合使用,从 1.5 秒开始的时间现在是 239 毫秒。 这是预编译的代码...

Func<DataClassesDataContext, int, IQueryable<Product>> compiledQuery =
    CompiledQuery.Compile((DataClassesDataContext meta, int IdToFind) =>
                          (from myData in meta.Products
                           where myData.ProductID.Equals(IdToFind)
                           select myData));

StringBuilder Test = new StringBuilder();
int[] MiaSeira = { 5, 6, 10, 100, 7 };

using (DataClassesDataContext context = new DataClassesDataContext())
{
    context.ObjectTrackingEnabled = false;

    for (int i = 0; i < 100; i++)
    {
        foreach (int EnaID in MiaSeira)
        {
            var oFindThat2P = compiledQuery(context, EnaID);

            foreach (Product One in oFindThat2P)
            {
                Test.Append("<br />");
                Test.Append(One.ProductName);
            }
        }
    }
}

优化 SubSonic 3 和问题

我做了很多性能分析,并开始一个接一个地更改,速度更好但仍然太慢。我将它们发布在亚音速组但他们忽略了这个问题,他们说一切都很快......

Here is some capture of my profiling and delay points inside subsonic source code

我最终认为 subsonic3 更多地调用数据库的结构而不是数据本身。需要重新考虑求数据的坑道,如果可能的话,按照subsonic2的思路。

尝试像我在 linq2Sql 中那样预编译到亚音速 3,但暂时失败了......

优化 SubSonic 2

在我发现亚音速 3 非常慢之后,我开始检查亚音速 2 - 在我认为它很快之前我从未做过。 (确实如此)

所以它提出了一些可以更快的点。例如 there are many loops like this ones 实际上很慢,因为字符串操作和循环内的比较。我必须对你说,这段代码被调用了百万次!上几分钟!程序要求的数据。

对于少量的表格和小字段,这对某些人来说可能不是什么大问题,

但在大量表上,延迟甚至更多。所以我自己决定和优化亚音速2,通过替换字符串比较,用数字比较!简单的。我几乎在分析器所说的每一个点上都这样做很慢。我还更改了所有可以更快一点的小点,并禁用了一些不常用的想法。

结果,在 NorthWind 数据库上快 5%,在我的拥有 250 个表的数据库上快近 20%。在北风的 10 秒内处理时间减少了 500 毫秒,在 500 毫秒的处理时间内在我的数据库上快了 100 毫秒。我没有截图可以展示给你,因为我用不同的代码、不同的时间制作了它们,并在纸上追踪它们。

无论如何,这是我的故事和我的问题,你还知道什么可以让它们更快......

为此,我使用了我优化的 Subsonic 2.2、我稍微优化的 Subsonic 3.0.0.3 和 Dot.Net 3.5

【问题讨论】:

  • 似乎很清楚 Subsonic 3 测试存在一些问题。也许是配置错误?
  • 对亚音速 3 的任何帮助! - 我也问过创作者,但不想评论那个速度。
  • 您的问题太模糊,无法得到任何有用的答案。您需要发布一个简单的示例,说明您的代码运行缓慢的确切部分。最好是其他人可以拿走自己进行比较的。在你能做到之前,我看不出任何人可以如何为你回答这个问题。
  • Dera Adam,我已经上传了项目,源代码在里面,很简单,请抓紧时间自己下载看看。
  • 如果您无法将确切的代码发布到问题中,那么我无法帮助您。您的基准不是基准,您不知道代码中的瓶颈在哪里。令人惊讶的是,我没有时间为您下载安装程序和调试您的项目。

标签: linq-to-sql subsonic subsonic3 benchmarking performance


【解决方案1】:

Aristos,这就是我遇到的问题。您向我们的小组发布了一个问题,我们进行了一次不错的 23 长的电子邮件交流。你坚持 SubSonic 3 有问题,你问我为什么我没有修复这个“缓慢、损坏的工具”。

我试图向您解释,对于 233 个表,SubSonic 必须在加载时读取每个表的架构。这不是 SubSonic 3 的典型用法,但我们这样做是因为它在后续加载时实际上比 SubSonic 2 更快。

你正在输入这个。我在回答你。 RBarry 在上面留下了一条评论,说我是在“诋毁”。我很沮丧。您似乎认为我没有对这件事进行基准测试,而且我有很多次。我无法制造出像您建议的那样存在问题的 ORM,而我没有。

你必须明白,如果 SubSonic 需要 10 秒来运行一个查询,那么它就不会被使用。

所以 - 你的答案是:233 个表,脚本化为类,需要在首次运行时加载到提供程序内存。

太多了。 SubSonic 不是你的工具。

【讨论】:

  • 亲爱的 Rob,我已经对你说过很多次了,我有 4 个数据库,只有一个有 233 个表,另一个只有 10 个表。即使在有 10 张桌子的情况下也会出现延迟。我所有的工作和报告都是为了帮助找出延迟的原因,以及如何解决它,或者告诉我如何纠正它。但是请我再说一遍,这里的测试是用 Northwind 数据库的。
  • Rob,我必须感谢你对亚音速 2 和亚音速 3 的感谢。亚音速 2 非常好,速度快,易于使用,并且经过一些优化后甚至更快(为什么你不赢得了这个额外优化的源代码?)。我从 subsonic 3 开始工作,它更容易,非常酷,非常好,我喜欢它 - 无论如何需要以速度工作,接受它并考虑如何修复它。其实我想问你,你用什么工具来测量他们两个的速度?你看到我的速度分析的屏幕截图了吗?你看到 subsonic 3 里面的实际延迟了吗?
  • Rob,这里非常有趣的想法是你仍然否认了这个问题,并且你没有尝试看看你做了什么来改进你的程序。你怎么看 ?那这个延迟是不存在的?这是罕见的情况?是我的错吗?为什么不接受它并尝试修复它?为什么不尝试改进呢?你永远不会通过避开批评者来制造完美的工具,或者对任何人说“亚音速不是你的工具”,只是因为他们发现了需要的错误和改进。 Rob,我没有你的任何东西,正如我所说的 Subsonic 2 超级酷和推荐,但 subsonic 3 需要工作。
  • 提交补丁或离开。我越来越厌倦你强迫性的挑衅。
【解决方案2】:

我认为要在这些方面获得更好的基准,您应该在 sql profiler 中检查时间,而不是在 google chrome 中,因为在浏览器中可能有很多因素会影响页面加载速度。

【讨论】:

  • 我已经禁用了所有的谷歌浏览器扩展,但是如果这个额外的时间存在,那么所有测试都是一样的。
  • 这意味着如果你刷新一个ORM的页面你会得到相同的数字,这是结果吗?
  • 是的!你得到相同的数字 - 我已经刷新页面 1 次进行编译,然后 3 次看到数字相同,然后我得到了捕获。
  • 问就好了。对我来说,我将要使用的工具的速度非常关键,所以我需要了解并与他人分享这种经验,并可能发现我犯的任何错误。正确的工具至关重要,因为我开始学习它,花时间使用它,经过数月和数年的开发,如果我发现自己犯了错误,那么回去使用其他东西是很痛苦的。
  • 亲爱的 Amr,我已经更新了这篇文章,以证明 google chrome 确实计算了我的要求,我还包含了更多的措施和更多的细节。
【解决方案3】:

您的速度测试是一个网页,在我看来,它看起来像是您测试加载需要多长时间。 SubSonic 并没有那么慢,而且在网页中测试加载时间是相当荒谬的。

如果您想真正对某些内容进行基准测试,您需要使用控制台并运行针对索引数据的读取循环。您所做的是创建一个网页并说“让我们看看加载时会发生什么”。

这是有缺陷的,原因有很多。首先 - 所有编写的代码都需要从 IL do ML 编译。因为 SubSonic 会为您生成代码,并且因为我知道您这里有很多表格(如果我没记错的话,超过 300 个),您可以想象在您第一次加载时有一些工作正在幕后进行。

老实说 - 你的缺乏经验正在取消我免费投入的大量工作,比如发布“它很慢而且还没有准备好”之类的东西。我不在乎人们是否使用 SubSonic - 当人们做愚蠢的事情(如基准网络测试)并为此责备我时,我确实很在意。

【讨论】:

  • 亲爱的 Rob,我测量的速度是获取数据所需的时间。加载页面的时间是下一个。示例在这里,请获取并随时创建一个新示例,或改进这个。
  • Rob,花点时间自己做一些测试,下载 chrome 看看它是如何工作的以及它显示了什么。有一种非常简单的方法可以显示什么是慢的,什么不是 - 为什么有些人不需要 chrome 来测量速度,因为差异非常大,你可以正确地感觉到 - 我理解某事正在发生的方式慢慢开始做测试。
  • 这个例子使用的是罗斯文数据库!如果您花时间下载并告诉我真正的问题!
  • 您的缺乏经验正在取消我免费投入的大量工作 - 免费并不是获得任何不工作的借口。你很有经验,为什么不把它跑得更快呢?我想在这里指出,您不是在这里谈论速度慢的主题,您对我说我没有经验,而您的第二个论点是免费的。这两个论点即使是对的,也不会改变我在这里发帖的速度!!!
  • -1:诋毁一个诚实、聪明且经过充分研究的问题,因为您与它的主题有个人关联。不恰当和不专业,海报语言困难不是借口。
【解决方案4】:

根据您的示例,您可以使用以下代码提高性能:

 StringBuilder Test = new StringBuilder();
 int[] MiaSeira = { 5, 6, 10, 100, 7 };
 for (int i = 0; i < 100; i++)
 {
     foreach (int EnaID in MiaSeira)
     {
         var Products = (from product in Product.
             where MiaSeira.Contains(product.ProductID)
             select product).ToList();

         if (Products == null || Products.Count == 0)
             continue;

         foreach (Product product in Products)
         {
            Test.Append("<br />");
            Test.Append(product.ProductName);
         }
     }
 }

 txtDebug.Text = Test.ToString();

【讨论】:

  • 亚当,感谢您抽出宝贵时间给我这个,但实际上我还有其他想法。所以我更新了这篇文章,给出了一个更好的主意。
  • 所以我给你一个解决方案,你马上改变你的问题,你现在有什么想法?
  • 我认为 Products 在这样使用时永远不会为空,而不是使用 Products.Count 您可以使用 Products.Any() ,它返回 true 列表中有记录,否则返回 false。
【解决方案5】:

我没有使用亚音速的第一手经验,但如果它正在生成大量代码,您可能希望发布第一个请求(冷)和后续请求(暖)的平均结果。您还应该使用秒表来计时只是数据提取部分,因此您不会将其他计时混为一谈。

【讨论】:

  • 好的,我会做的,请给我一些时间。
  • Jimmy 我已经更新了这篇文章,包括现在连续捕获 4-5 个请求,以及许多其他信息
猜你喜欢
  • 1970-01-01
  • 2010-11-03
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多