On Wed, 2009-06-17 at 03:49 +0000, Jonathan Pryor wrote:
> Things I find truly interesting is that the DataContext constructor is
> *slow* (which shouldn't be too surprising, as Adrus Moor already told us
> this), but at 348820 ticks to execute it is the most expensive step,
> taking over 3x longer than actually executing the SQL query.
>
> This is insane.
And this has been improved by making AttributedMetaModel lazily
initialize itself in r1171.
Before r1171, DataContext construction was around 350000 ticks within
the unit tests.
In r1171, DataContext construction is around 400 ticks.
Yes, that's around 875x faster.
It's not without it's tradeoffs, though.
Test_NUnit_MsSql.AnyCount.CountExternal03:
Before:
Step 1: 348820 ticks
Step 2: 21105
Step 3: 133918
Step 4: 1850
Step 5: 114779
Total: 620570
After [0]: [ (new / old)*100 % ]
Step 1: 433 ticks [ 0.12% ]
Step 2: 244219 [ 1157.16% ]
Step 3: 45254 [ 33.79% ]
Step 4: 2062 [ 111.46% ]
Step 5: 90545 [ 78.89% ]
Total: 382781 [ 61.68% ]
So for this test, step 2 (the Expression<T> creation) was
*significantly* slower, taking ~12x longer. Step 3, meanwhile, was ~3x
faster, while steps 4 and 5 were roughly comparable (-ish).
Despite Step 2 taking ~12x longer, the entire test ran faster.
That's a trade-off I'm willing to make. :-)
Next we look at
Test_NUnit_MsSql.ReadTest_Complex.F26_DistinctUnion_Count:
Before:
Step 1: 360714 ticks
Step 2: 104669
Step 3: 2829379
Step 4: 549125
Step 5: 2241118
Total: 6523817
After [1]: [ (new / old)*100 % ]
Step 1: 369 ticks [ 0.10% ]
Step 2: 128496 [ 122.76% ]
Step 3: 252783 [ 8.93% ]
Step 4: 8302 [ 1.51% ]
Step 5: 137859 [ 6.15% ]
Total: 528024 [ 8.09% ]
All I can say is, _wow_.
With a win like that, I'm wondering if I need to make anything else
lazy...
(With wins like that, I wonder if QueryCache is needed as much any
more...)
Analysis? Alas, I can't say _why_ this is happening, but I can
conjecture (badly). Step 2 is uniformly slower because the table
loading that used to be performed in the AttributedMetaModel constructor
is now performed during DataContext.GetTable<T>() (via
AttributedMetaModel.GetTable(Type)), so it's largely a movement of time
accounting away from the constructor into Step 2.
Furthermore, while debugging this I'm seeing that some of the laziness
is defeated, as AttributedMetaAssociation.SetupRelationship() starts
pulling in more and more types. However, at least it's restricted to
just the T in Table<T> that's being accessed, instead of all types all
at once (which should still speed up things for Andrus Moor). If I'm
lucky this can be made even lazier.
- Jon
[0] Test_NUnit_MsSql.AnyCount.CountExternal03
#AT(time=0000000011, elapsed=0000000011) BaseSetUp()
#AT(time=0000106794, elapsed=0000106783) START DataContext(IDatabaseContext,
MappingSource, IVendor)
#AT(time=0000107227, elapsed=0000000433) END DataContext(IDatabaseContext,
MappingSource, IVendor)
#AT(time=0000107439, elapsed=0000000212) DataContext.GetTable(typeof(Customer))
#AT(time=0000351658, elapsed=0000244219) START QueryProvider.Execute<Int32>():
Executing expression...
#AT(time=0000351703, elapsed=0000000045) START: GetSelectQuery(), building
Expression query
Call (MethodCallExpression)
..Object: (null)
..Method: Count
..#00000 Constant (ConstantExpression)
....Value: Table(Customer)
#AT(time=0000396957, elapsed=0000045254) END: GetSelectQuery(), building
Expression query
#AT(time=0000396968, elapsed=0000000011) START: GetSelectQuery(), building Sql
query
#AT(time=0000399030, elapsed=0000002062) END: GetSelectQuery(), building Sql
query
SELECT COUNT(*)
FROM [dbo].[Customers]
-- Context: SqlServer Model: AttributedMetaModel Build: 0.19.0.0
#AT(time=0000489575, elapsed=0000090545) END QueryProvider.Execute<Int32>():
Executing expression...
#AT(time=0000489741, elapsed=0000000166) BaseTearDown()
[1] Test_NUnit_MsSql.ReadTest_Complex.F26_DistinctUnion_Count
#AT(time=0000000012, elapsed=0000000012) BaseSetUp()
#AT(time=0000092065, elapsed=0000092053) START DataContext(IDatabaseContext,
MappingSource, IVendor)
#AT(time=0000092434, elapsed=0000000369) END DataContext(IDatabaseContext,
MappingSource, IVendor)
#AT(time=0000092592, elapsed=0000000158) DataContext.GetTable(typeof(Territory))
#AT(time=0000216684, elapsed=0000124092) START
QueryProvider.CreateQuery<Territory>(Table(Territory).Where(t =>
t.TerritoryDescription.StartsWith("A")))
#AT(time=0000216722, elapsed=0000000038) END
QueryProvider.CreateQuery<Territory>(...)
#AT(time=0000216760, elapsed=0000000038) DataContext.GetTable(typeof(Territory))
#AT(time=0000218352, elapsed=0000001592) START
QueryProvider.CreateQuery<Territory>(Table(Territory).Where(terr =>
terr.TerritoryDescription.Contains("i")))
#AT(time=0000218398, elapsed=0000000046) END
QueryProvider.CreateQuery<Territory>(...)
#AT(time=0000219668, elapsed=0000001270) START
QueryProvider.CreateQuery<Territory>(value(DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]).Concat(value(DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory])))
#AT(time=0000219716, elapsed=0000000048) END
QueryProvider.CreateQuery<Territory>(...)
#AT(time=0000220560, elapsed=0000000844) START
QueryProvider.CreateQuery<Territory>(value(DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]).Distinct())
#AT(time=0000220623, elapsed=0000000063) END
QueryProvider.CreateQuery<Territory>(...)
#AT(time=0000221088, elapsed=0000000465) START QueryProvider.Execute<Int32>():
Executing expression...
#AT(time=0000221134, elapsed=0000000046) START: GetSelectQuery(), building
Expression query
Call (MethodCallExpression)
..Object: (null)
..Method: Where
..#00000 Constant (ConstantExpression)
....Value: Table(Territory)
..#00001 Quote (UnaryExpression)
....Method :
....Operand Lambda (Expression`1)
......Call Call (MethodCallExpression)
........Object MemberAccess (MemberExpression)
..........Object Parameter (ParameterExpression)
............Parameter: t
..........Member: TerritoryDescription
........Method: StartsWith
........#00000 Constant (ConstantExpression)
..........Value: A
......#000 Parameter (ParameterExpression)
........Parameter: t
Call (MethodCallExpression)
..Object: (null)
..Method: Concat
..#00000 Constant (ConstantExpression)
....Value: DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]
..#00001 Constant (ConstantExpression)
....Value: DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]
Call (MethodCallExpression)
..Object: (null)
..Method: Distinct
..#00000 Constant (ConstantExpression)
....Value: DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]
Call (MethodCallExpression)
..Object: (null)
..Method: Count
..#00000 Constant (ConstantExpression)
....Value: DbLinq.Data.Linq.Implementation.QueryProvider`1[nwind.Territory]
#AT(time=0000473917, elapsed=0000252783) END: GetSelectQuery(), building
Expression query
#AT(time=0000473928, elapsed=0000000011) START: GetSelectQuery(), building Sql
query
#AT(time=0000482230, elapsed=0000008302) END: GetSelectQuery(), building Sql
query
SELECT COUNT(*)
FROM (SELECT DISTINCT *
FROM (SELECT t$.[TerritoryID], t$.[TerritoryDescription], t$.[RegionID]
FROM [dbo].[Territories] AS t$
WHERE (t$.[TerritoryDescription] LIKE 'A%')
UNION ALL
SELECT terr$.[TerritoryID], terr$.[TerritoryDescription], terr$.[RegionID]
FROM [dbo].[Territories] AS terr$
WHERE (terr$.[TerritoryDescription] LIKE '%i%')) AS source1$) AS source$
-- Context: SqlServer Model: AttributedMetaModel Build: 0.19.0.0
#AT(time=0000620089, elapsed=0000137859) END QueryProvider.Execute<Int32>():
Executing expression...
#AT(time=0000620294, elapsed=0000000205) BaseTearDown()
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---