Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Core/10.0.300.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Optimize Set.intersect performance symmetry and preserve identity from the first set argument. ([PR #19292](https://github.com/dotnet/fsharp/pull/19291)) (Fixes #19292)
* Fix anonymous record field ordering in LINQ expression conversion to produce consistent expression trees regardless of field declaration order. ([Issue #11131](https://github.com/dotnet/fsharp/issues/11131), [Issue #15648](https://github.com/dotnet/fsharp/issues/15648))
* Fix array indexing in LINQ expressions to generate proper array index expressions instead of GetArray method calls, enabling LINQ providers like Azure Cosmos DB to translate array access. ([Issue #16918](https://github.com/dotnet/fsharp/issues/16918))
* Fix tuple join conditions and groupBy operations to properly compare tuple keys using structural equality. AnonymousObject types now implement Equals and GetHashCode, enabling inline tuple joins like `join b on ((a.Id1, a.Id2) = (b.Id1, b.Id2))` to work correctly. ([Issue #7885](https://github.com/dotnet/fsharp/issues/7885), [Issue #47](https://github.com/dotnet/fsharp/issues/47))
Expand Down
41 changes: 40 additions & 1 deletion src/FSharp.Core/set.fs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,21 @@ module internal SetTree =
elif c = 0 then true
else mem comparer k tn.Right

let rec tryGet (comparer: IComparer<'T>) k (t: SetTree<'T>) =
if isEmpty t then
None
else
let c = comparer.Compare(k, t.Key)

if t.Height = 1 then
if c = 0 then Some t.Key else None
else
let tn = asNode t

if c < 0 then tryGet comparer k tn.Left
elif c = 0 then Some tn.Key
else tryGet comparer k tn.Right

let rec iter f (t: SetTree<'T>) =
if isEmpty t then
()
Expand Down Expand Up @@ -391,6 +406,24 @@ module internal SetTree =

balance comparer (union comparer t2n.Left lo) t2n.Key (union comparer t2n.Right hi)

let rec intersectionAuxFromSmall comparer a (t: SetTree<'T>) acc =
if isEmpty t then
acc
else if t.Height = 1 then
match tryGet comparer t.Key a with
| Some v -> add comparer v acc
| None -> acc
else
let tn = asNode t
let acc = intersectionAuxFromSmall comparer a tn.Right acc

let acc =
match tryGet comparer tn.Key a with
| Some v -> add comparer v acc
| None -> acc

intersectionAuxFromSmall comparer a tn.Left acc

let rec intersectionAux comparer b (t: SetTree<'T>) acc =
if isEmpty t then
acc
Expand All @@ -412,7 +445,13 @@ module internal SetTree =
intersectionAux comparer b tn.Left acc

let intersection comparer a b =
intersectionAux comparer b a empty
let n1 = count a
let n2 = count b

if n1 <= n2 then
intersectionAux comparer b a empty
else
intersectionAuxFromSmall comparer a b empty

let partition1 comparer f k (acc1, acc2) =
if f k then
Expand Down
Loading