基准 Linq2SQL、Subsonic2、Subsonic3 - 还有其他想法可以使它们更快吗?
我现在使用 Subsonic 2 已超过 3 年了...
在 Linq 出现,然后是 Subsonic 3 后,我开始考虑迁移到连接到 sql 的新 Linq future。
我必须说,我开始移动我的 Subsonic 2 和 SubSonic 3,很快我发现速度太慢了,我简直不敢相信 - 然后开始所有测试。
然后我测试 Linq2Sql 并看到延迟 - 将其与 Subsonic 2 进行比较。
我的问题是,特别是对于 linq2sql 和即将推出的 dotnet 版本 4,我还能做些什么来加快速度? linq2sql 设置或类上还有什么,而不是我用于测量的代码,
我将进行测试的项目以及结果的屏幕截图放在这里。
我如何进行测试 - 以及我的测量的准确性。
我只使用 Google chrome 来解决我的问题,因为我很难在这里展示我用更复杂的程序完成的许多其他措施。这是最简单的,我只是测量Data Read。我该如何证明这一点。我做了一个简单的 Thread.Sleep(10 秒),看看我是否在 Google Chrome Measure 上看到了 10 秒,是的,我看到了。
(来源:planethost.gr)
这里有更多测试睡一觉,看看 Chrome 到底能提供什么。
只有 15ms 的延迟,相比之下太小了它与我不关心的其余测试一起。
所以我测量
的只是通过每种方法读取的数据 - 没有计算数据或数据库延迟,或任何磁盘读取或类似的东西。稍后的结果图像显示,测量中不存在磁盘活动
查看此图片以了解我真正测量的内容以及这是否正确
我选择的原因这种测试
很简单,很真实,而且很接近我真正的问题,我在真实程序中用真实数据发现了亚音速3的延迟。
现在让我们测试 dals
从查看此图片开始 我对每个方法都调用了 4-5 次,一个接一个。
结果是。 对于 100 次循环,大约要求 5 行,其中一行不存在。
简单的adonet:81ms
亚音速 2:210ms
linq2sql:1.70秒
linq2sql 使用 CompiledQuery.Compile :239ms
Subsonic 3:15.00sec(哇 - 极慢)
该项目 http://www.planethost.gr/DalSpeedTests.rar
任何人都可以确认这个基准,或者进行任何优化来帮助我吗?
其他测试
有人在这里发布此链接http://ormbattle.net/(然后将其删除 - 不知道为什么)在此页面中,您可以找到对所有人来说非常有用的高级测试,除了我这里的亚音速 2 和亚音速 3 之外!
优化
我在这里真正要问的是,是否有人现在可以找到任何优化 DAL 的技巧,不是通过更改测试代码,而是通过更改每个 dal 上的代码和设置。 例如...
优化 Linq2SQL
我开始搜索如何优化 Linq2sql 并发现 这篇文章,也许还有更多。
最后,我使该页面中的技巧得以运行,并使用它们来优化代码。速度从 1.70 秒接近 1.50 秒……进步很大,但仍然很慢。
然后我发现了 不同的方式 - 相同的想法文章,哇!速度被炸飞了。 将此技巧与 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 和问题
我做了很多性能分析,并开始一个接一个地更改,速度更好,但仍然太慢。我将它们发布在亚音速组上,但他们忽略了这个问题,他们说一切都很快...
我最终发现 subsonic3 更多地调用了数据库的结构而不是数据本身。需要重新考虑请求数据的方式,如果可能的话,遵循 subsonic2 的想法。
尝试像我在 linq2Sql 中那样对 subsonic 3 进行预编译,但暂时失败了...
优化 SubSonic 2
在我发现 subsonic 3 非常慢之后,我开始对 subsonic 2 进行检查 - 在相信这是之前我从未做过的检查快速地。 (确实如此)
所以它提出了一些可以更快的点。例如有很多像这样的循环,由于字符串操作和内部比较,实际上很慢循环。我必须告诉你,这段代码被调用了数百万次!就几分钟的时间!从程序请求的数据。
在少量表和小字段上,对于某些人来说这可能不是一个大问题,
但在大量表上,延迟甚至更多。所以我自己决定并优化亚音速2,将字符串比较替换为数字比较!简单的。我几乎在分析器所说的缓慢的每一点上都这样做。我还更改了所有可以更快一点的小点,并禁用了一些不那么常用的想法。
结果,NorthWind 数据库的速度提高了 5%,在包含 250 个表的数据库上速度提高了近 20%。在 Northwind 上,10 秒的处理时间减少了 500 毫秒,在我的数据库上,500 毫秒的处理时间快了 100 毫秒。我没有捕获的内容向您展示,因为我用不同的代码、不同的时间制作了它们,并在纸上追踪它们。
无论如何,这是我的故事和我的问题,你还知道什么可以让它们更快......
对于这个措施,我使用了我优化的 Subsonic 2.2,Subsonic 3.0.0.3 一点由我优化,Dot.Net 3.5
I am working with Subsonic 2 more than 3 years now...
After Linq appears and then Subsonic 3, I start thinking about moving to the new Linq futures that are connected to sql.
I must say that I start move and port my subsonic 2 with SubSonic 3, and very soon I discover that the speed was so slow thats I didn't believe it - and starts all that tests.
Then I test Linq2Sql and see also a delay - compare it with Subsonic 2.
My question here is, especial for the linq2sql, and the up-coming dotnet version 4, what else can I do to speed it up ? What else on linq2sql settings, or classes, not on this code that I have used for my messures
I place here the project that I make the tests, also the screen shots of the results.
How I make the tests - and the accurate of my measures.
I use only for my question Google chrome, because its difficult for me to show here a lot of other measures that I have done with more complex programs. This is the most simple one, I just measure the Data Read. How can I prove that. I make a simple Thread.Sleep(10 seconds) and see if I see that 10 seconds on Google Chrome Measure, and yes I see it.
(source: planethost.gr)
here are more test with this Sleep thead to see whats actually Chrome gives.
10 seconds delay
100 ms delay
Zero delay
There is only a small 15ms thats get on messure, is so small compare it with the rest of my tests that I do not care about.
So what I measure
I measure just the data read via each method - did not count the data or database delay, or any disk read or anything like that. Later on the image with the result I show that no disk activity exist on the measures
See this image to see what really I measure and if this is correct
Why I chose this kind of test
Its simple, it's real, and it's near my real problem that I found the delay of subsonic 3 in real program with real data.
Now lets tests the dals
Start by see this image
I have 4-5 calls on every method, the one after the other.
The results are.
For a loop of 100 times, ask for 5 Rows, one not exist, approximatively..
Simple adonet:81ms
SubSonic 2 :210ms
linq2sql :1.70sec
linq2sql using CompiledQuery.Compile :239ms
Subsonic 3 :15.00sec (wow - extreme slow)
The project
http://www.planethost.gr/DalSpeedTests.rar
Can any one confirm this benchmark, or make any optimizations to help me out ?
Other tests
Some one publish here this link http://ormbattle.net/ (and then remove it - don not know why) In this page you can find a really useful advanced tests for all, except subsonic 2 and subsonic 3 that I have here !
Optimizing
What I really ask here is if some one can now any trick how to optimize the DALs, not by changing the test code, but by changing the code and the settings on each dal.
For example...
Optimizing Linq2SQL
I start search how to optimize Linq2sql and found
this article, and maybe more exist.
Finally I make the tricks from that page to run, and optimize the code using them all. The speed was near 1.50sec from 1.70.... big improvement, but still slow.
Then I found a different way - same idea article, and wow ! the speed is blow up.
Using this trick with CompiledQuery.Compile, the time from 1.5sec is now 239ms.
Here is the code for the precompiled...
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);
}
}
}
}
Optimizing SubSonic 3 and problems
I make many performance profiling, and start change the one after the other and the speed is better but still too slow. I post them on subsonic group but they ignore the problem, they say that everything is fast...
Here is some capture of my profiling and delay points inside subsonic source code
I have end up that subsonic3 make more call on the structure of the database rather than on data itself. Needs to reconsider the hole way of asking for data, and follow the subsonic2 idea if this is possible.
Try to make precompile to subsonic 3 like I did in linq2Sql but fail for the moment...
Optimizing SubSonic 2
After I discover that subsonic 3 is extreme slow, I start my checks on subsonic 2 - that I have never done before believing that is fast. (and it is)
So its come up with some points that can be faster. For example there are many loops like this ones that actually is slow because of string manipulation and compares inside the loop. I must say to you that this code called million of times ! on a period of few minutes ! of data asking from the program.
On small amount of tables and small fields maybe this is not a big think for some people,
but on large amount of tables, the delay is even more. So I decide and optimize the subsonic 2 by my self, by replacing the string compares, with number compares! Simple. I do that almost on every point that profiler say that is slow. I change also all small points that can be even a little faster, and disable some not so used thinks.
The results, 5% faster on NorthWind database, near 20% faster on my database with 250 tables. That is count with 500ms less in 10 seconds process on northwind, 100ms faster on my database on 500ms process time. I do not have captures to show you for that because I have made them with different code, different time, and track them down on paper.
Anyway this is my story and my question on all that, what else do you know to make them even faster...
For this measures I have use Subsonic 2.2 optimized by me, Subsonic 3.0.0.3 a little optimized by me, and Dot.Net 3.5
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
阿里斯托斯,这就是我遇到的问题。您向我们的小组提出了一个问题,我们进行了长达 23 次的愉快的电子邮件交流。您坚称 SubSonic 3 有问题,并问我为什么没有修复这个“缓慢、损坏的工具”。
我试图向您解释,对于 233 个表,SubSonic 必须在加载时读取每个表的模式。这不是 SubSonic 3 的典型用法,但我们这样做,因此在后续加载中它实际上比 SubSonic 2 更快。
你正在接受这个。我正在回答你。 RBarry 在上面留言说我是在“诽谤”。我很沮丧。你似乎认为我没有对这件事进行基准测试,但我已经做了很多很多次了。我无法生成一个存在像你所建议的问题的 ORM,而且我也没有这样做。
您必须了解,如果 SubSonic 需要 10 秒来运行查询,那么它就不会被使用。
所以 - 你的答案是:233 个表,以类的形式编写,需要在第一次运行时加载到提供程序内存中。
太多了。 SubSonic 不是您的工具。
Aristos, here's the thing I'm having an issue with. You posted a question to our groups and we had a nice, 23-long email exchange. You insisted that SubSonic 3 has problems and you asked me why I haven't fixed this "slow, broken tool".
I tried to explain to you that, with 233 tables, SubSonic has to read the schema of EACH ONE on load up. This isn't typical usage for SubSonic 3, but we do it this way so it's actually FASTER than SubSonic 2 on subsequent loadups.
You're ingoring this. I'm answering you. RBarry left a comment above that I was beind "denigrating". I'm quite frustrated. You seem to think that I haven't benchmarked this thing and I have, MANY MANY times. I can't turn out an ORM with problems like the one you suggested, and I didn't.
You have to understand that if it took SubSonic 10 seconds to run a query, then it wouldn't be used.
So - your answer: 233 tables, scripted out as classes, need to load to Provider memory on first run.
That's too many. SubSonic isn't your tool.
我认为要获得更好的基准,您应该在 sql profiler 中检查时间,而不是在 google chrome 中检查时间,因为在浏览器中可能有很多事情会影响页面加载的速度。
I think to get a better Benchmark on these, you should check the time in sql profiler not in google chrome, because in the browser it may be a lot of things affect the speed on the page load.
您的速度测试是一个网页,在我看来,它看起来就像您测试加载需要多长时间。 SubSonic 并没有那么慢,并且在网页中测试加载时间是相当荒谬的。
如果您想真正对某些内容进行基准测试,则需要使用控制台并运行针对索引数据的读取循环。您所做的就是创建一个网页并说“让我们看看加载时会发生什么”。
由于多种原因,这是有缺陷的。首先 - 所有编写的代码都需要从 IL do ML 编译。因为 SubSonic 会为您生成代码,并且因为我知道您这里有很多表(如果我没记错的话,有 300 多个表),所以您可以想象在第一次加载时有一些工作在幕后进行。
在这里说实话 - 你的经验不足正在抵消我免费投入的大量工作,通过发布诸如“它很慢而且还没有准备好”之类的东西。我不在乎人们是否使用 SubSonic - 我确实在乎人们做了愚蠢的事情(比如基准网络测试)并因此责备我。
Your speed test is a web page that, to my eyes, looks like your testing how long it takes to load. SubSonic isn't that slow and testing load time in a web page is rather ridiculous.
If you want to truly benchmark something you need to use a Console and run read loops that work against indexed data. What you've done is create a web page and say "let's see what happens on load".
This is flawed for a number of reasons. First - all of the code written needs to be compiled from IL do ML. Because SubSonic generates your code for you, and because I know you have a lot of tables here (300+ if I remember right), you can imagine there's some work going on under the covers on your first load.
To be perfectly honest here - your inexperience is undoing a lot of work I've put in for free, by posting things like "it's slow and not ready". I don't care if people use SubSonic - I do care when people do dumb things (like benchmark web tests) and blame me for it.
根据您的示例,您可以使用以下代码来提高性能:
Based on your example you can improve the performance by using the following code:
我没有亚音速方面的第一手经验,但如果它正在生成大量代码,您可能需要发布第一个请求(冷)的单独结果,以及后续请求的平均值(热)。您还应该使用秒表来为数据提取部分计时,这样您就不会将其他计时混入数据中。
I don't have firsthand experience with subsonic, but if it is doing a bunch of code generation, you might want to post separate results for the first request (cold), and an average of subsequent requests (warm). You should also use a Stopwatch to time just the data extraction part, so you don't conflate other timings into your data.