问题描述
我只是测试一个简单的查询,我以不同的方式访问,但每个的速度可以变化最多2秒。我希望有人能澄清为什么会这样。我的项目是在很早的阶段,所以我以为我会确定我在做的太大了之前。
诚然,我的测试风格并不完美,但我认为这样做够好。
'使用通用的Repository和UnitofWork,并且我在这个而
语句中打数据库(本地机器上的sqlexpress)10,000次。该表只有64条记录。测试运行在发布模式。
[TestMethod]
public void MyTestMethod()
{
using(var u = new UnitOfWork())
{
TestA(u);
TestB(u);
}
}
TestA(Func):
public void TestA(UnitOfWork u)
{
秒表s = Stopwatch.StartNew();
s.Start();
var x = 0;
var repo = u.Repository< MyEntity>();
var code =ABCD.First()。ToString();
while(x< 10000)
{
var testCase = repo.Single(w => w.Code == code&& w.CodeOrder == 0) ;
x ++;
}
s.Stop();
Console.WriteLine(TESTA:+ s.Elapsed);
}
TestB(Expression):
public void TestB(UnitOfWork u)
{
秒表s = Stopwatch.StartNew();
s.Start();
var x = 0;
var repo = u.Repository< MyEntity>();
var code =ABCD.First()。ToString();
while(x< 10000)
{
var testCase = repo.First(w => w.Code == code&& w.CodeOrder == 0) ;
x ++;
}
s.Stop();
Console.WriteLine(TESTB:+ s.Elapsed);
}
即使我正在使用电话 First )
和 Single()
,它们不是内置的LINQ调用。他们是我的存储库的一部分。
First()
expression(IQueryable)
public TEntity Single(Func< TEntity,bool>谓词)
{
return dbSet.FirstOrDefault(predicate);
}
Single()
func(IEnumerable)
public TEntity First(Expression< Func< TEntity,bool>> predicate)
{
return dbSet.FirstOrDefault(predicate);
}
输出:
$ b $测试结果:通过结果StandardOutput:
TESTA: 00:00:02.4798818
TESTB:00:00:03.4212112
这不是一个答案,而只是试图确保测试结果更可靠。
尝试写这样的测试:
public long TestA()
{
using(var u = new UnitOfWork())
{
var s = Stopwatch.StartNew();
var x = 0;
var repo = u.Repository< MyEntity>();
var code =ABCD.First()。ToString();
while(x< 10000)
{
var testCase = repo.Single(w => w.Code == code&& w.CodeOrder == 0) ;
x ++;
}
s.Stop();
return s.ElapsedMilliseconds;
}
}
(显然 TestB
只是一个小的变体。)
然后你的测试方法变成:
[TestMethod]
public void MyTestMethod()
{
var dummyA = TestA();
var dummyB = TestB();
var realA = 0L;
var realB = 0L; $ var $ i $ = $;
$
realB + = TestB();
}
Console.WriteLine(TESTA:+ realA.ToString());
Console.WriteLine(TESTB:+ realA.ToString());
}
现在,您的结果可能更准确。让我们知道现在的时间。
现在尝试更改这样的测试:
public int TestA()
{
var gc0 = GC.CollectionCount(0);
using(var u = new UnitOfWork())
{
var s = Stopwatch.StartNew();
var x = 0;
var repo = u.Repository< MyEntity>();
var code =ABCD.First()。ToString();
while(x< 10000)
{
var testCase = repo.Single(w => w.Code == code&& w.CodeOrder == 0) ;
x ++;
}
s.Stop();
}
return GC.CollectionCount(0) - gc0;
}
这应该确定正在执行多少代0个垃圾回收。这可能表明性能问题是您的测试而不是SQL。
I was just testing a simple query that i'm accessing in different ways, but the speed of each can vary by up to 2 seconds. I was hoping someone can clarify why this is the case. My project is in it's very early stages, so I thought I'd make sure I'm doing it right before it gets too big.
Admittedly, my testing style isn't perfect, but i think it's good enough for this.
I'm using a generic Repository and UnitofWork, and I hit the DB (sqlexpress on my local machine) 10,000 times in this while
statement. The table only has 64 records. Tests are run in Release mode.
[TestMethod]
public void MyTestMethod()
{
using (var u = new UnitOfWork())
{
TestA(u);
TestB(u);
}
}
TestA (Func):
public void TestA(UnitOfWork u)
{
Stopwatch s = Stopwatch.StartNew();
s.Start();
var x = 0;
var repo = u.Repository<MyEntity>();
var code = "ABCD".First().ToString();
while (x < 10000)
{
var testCase = repo.Single(w => w.Code == code && w.CodeOrder == 0).Name;
x++;
}
s.Stop();
Console.WriteLine("TESTA: " + s.Elapsed);
}
TestB (Expression):
public void TestB(UnitOfWork u)
{
Stopwatch s = Stopwatch.StartNew();
s.Start();
var x = 0;
var repo = u.Repository<MyEntity>();
var code = "ABCD".First().ToString();
while (x < 10000)
{
var testCase = repo.First(w => w.Code == code && w.CodeOrder == 0).Name;
x++;
}
s.Stop();
Console.WriteLine("TESTB: " + s.Elapsed);
}
Even though i'm using the calls First()
and Single()
, they're not the built-in LINQ calls. They're part of my repository.
First()
expression (IQueryable)
public TEntity Single(Func<TEntity, bool> predicate)
{
return dbSet.FirstOrDefault(predicate);
}
Single()
func (IEnumerable)
public TEntity First(Expression<Func<TEntity, bool>> predicate)
{
return dbSet.FirstOrDefault(predicate);
}
Output:
Test Name: MyTestMethod
Test Outcome: Passed
Result StandardOutput:
TESTA: 00:00:02.4798818
TESTB: 00:00:03.4212112
This is not an answer, but just trying to make sure that the test results are more reliable.
Try writing your tests like this:
public long TestA()
{
using (var u = new UnitOfWork())
{
var s = Stopwatch.StartNew();
var x = 0;
var repo = u.Repository<MyEntity>();
var code = "ABCD".First().ToString();
while (x < 10000)
{
var testCase = repo.Single(w => w.Code == code && w.CodeOrder == 0).Name;
x++;
}
s.Stop();
return s.ElapsedMilliseconds;
}
}
(Obviously TestB
is just a minor variant.)
And then your test method becomes:
[TestMethod]
public void MyTestMethod()
{
var dummyA = TestA();
var dummyB = TestB();
var realA = 0L;
var realB = 0L;
for (var i = 0; i < 10; i++)
{
realA += TestA();
realB += TestB();
}
Console.WriteLine("TESTA: " + realA.ToString());
Console.WriteLine("TESTB: " + realA.ToString());
}
Now your results are likely to be more accurate. Let us know the timings now.
Now try changing your tests like this:
public int TestA()
{
var gc0 = GC.CollectionCount(0);
using (var u = new UnitOfWork())
{
var s = Stopwatch.StartNew();
var x = 0;
var repo = u.Repository<MyEntity>();
var code = "ABCD".First().ToString();
while (x < 10000)
{
var testCase = repo.Single(w => w.Code == code && w.CodeOrder == 0).Name;
x++;
}
s.Stop();
}
return GC.CollectionCount(0) - gc0;
}
This should determine how many generation 0 garbage collections are being performed. That might indicate that the performance issues are with your tests and not with the SQL.
这篇关于Linq to Entities表现/功能之间的性能差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!