DelegateDecompiler icon indicating copy to clipboard operation
DelegateDecompiler copied to clipboard

Performance regression from 0.31.0 to 0.32.0

Open NetMastr5 opened this issue 2 years ago • 1 comments

When applying a where clause that has more then ~10 conditions, V0.32.0 is slower then V0.31.0, and this slowness seems to be exponential to the number of conditions in the filter.

This is on .Net Framework 4.8, Entity Framework 6.4.4

locationIds is a list of numbers
LOC.locationId is the primary key

~~~Test Code~~~
Expression<Func<LOC, bool>> filter = UniversalPredicateBuilder.False<LOC>();

foreach (decimal id in locationIds)
	filter = filter.Or(x => x.locationId == id);

var final2 = this.context.LOC.Where(filter);

DateTime now1 = DateTime.Now;
var final3 = final2.Decompile();
Debug.WriteLine($"{i} - {(DateTime.Now - now1).TotalMilliseconds}");
Debug.Flush();

~~~Results~~~
# of IDs in list			V0.32 (ms)	V0.31 (ms)
1					0			0
2					0			0
3					5.9823		0
4					0			0
5					0			0
6					0			0
7					0			0
8					0			0
9					0			0
10					0.9965		0
11					0.9963		0
12					33.9375		0
13					77.6428		0
14					176.3968		0
15					294.0033		0
16					518.0765		0
17					74.7487		0
18					130.652		0
19					114.7691		0
20					277.2769		0
21					520.9336		0
22					1030.82		0
23					2042.5927	0
24					3369.2147	0
25					7161.9973	0
26					12517.4393	0
27					24512.0805	0
28					47910.7318	0.9965
29					94613.1383	0
30					188813.2178	0


~~~Other Notes~~~
this.context.LOC.Where(x => locationIds.Contains(x.locationId)) has the same performance between V0.31 and V0.32
Breaking up the filter into parts limits the effect to the size of an individual filter level
        Expression<Func<LOC, bool>> filter1 = UniversalPredicateBuilder.False<LOC>();
        foreach (decimal id in locationIds.Take(10))
	        filter1 = filter1.Or(x => x.locationId == id);
        
        Expression<Func<LOC, bool>> filter2 = UniversalPredicateBuilder.False<LOC>();
        foreach (decimal id in locationIds.Skip(10).Take(10))
	        filter2 = filter2.Or(x => x.locationId == id);
        
        Expression<Func<LOC, bool>> filter3 = UniversalPredicateBuilder.False<LOC>();
        foreach (decimal id in locationIds.Skip(20))
	        filter3 = filter3.Or(x => x.locationId == id);
        
        
        Expression<Func<LOC, bool>> filter = UniversalPredicateBuilder.False<LOC>();
        
        filter = filter
	        .Or(filter1)
	        .Or(filter2)
	        .Or(filter3);
        
        var final2 = this.context.LOC.Where(filter);
        
        DateTime now1 = DateTime.Now;
        var final3 = final2.Decompile();
        Debug.WriteLine($"{i} - {(DateTime.Now - now1).TotalMilliseconds}");
        Debug.Flush();

NetMastr5 avatar Jul 31 '23 16:07 NetMastr5