Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More IndexOf() optimization #20083

Merged
merged 5 commits into from Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -200,25 +200,11 @@ void AddContact(ObservableCollection<Group> contactGroups, Contact contact)
InsertBasedOnSort(collection, contact, c => GetSortString(c)[0]);
}

int IndexOf<T>(IEnumerable<T> elements, T element)
{
int i = 0;
foreach (T e in elements)
{
if (Equals(e, element))
return i;

i++;
}

return -1;
}

void InsertBasedOnSort<T, TSort>(IList<T> items, T item, Func<T, TSort> sortBy)
{
List<T> newItems = new List<T>(items);
newItems.Add(item);
int index = IndexOf(newItems.OrderBy(sortBy), item);
int index = newItems.OrderBy(sortBy).IndexOf(item);
items.Insert(index, item);
}

Expand Down
Expand Up @@ -137,7 +137,7 @@ void Move(NotifyCollectionChangedEventArgs args)

void Add(NotifyCollectionChangedEventArgs args)
{
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
startIndex = AdjustPositionForHeader(startIndex);
var count = args.NewItems.Count;

Expand Down Expand Up @@ -178,7 +178,7 @@ void Remove(NotifyCollectionChangedEventArgs args)

void Replace(NotifyCollectionChangedEventArgs args)
{
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
startIndex = AdjustPositionForHeader(startIndex);
var newCount = args.NewItems.Count;

Expand Down Expand Up @@ -229,21 +229,5 @@ internal object ElementAt(int index)

return -1;
}

internal int IndexOf(object item)
{
if (_itemsSource is IList list)
return list.IndexOf(item);

int count = 0;
foreach (var i in _itemsSource)
{
if (i == item)
return count;
count++;
}

return -1;
}
}
}
Expand Up @@ -154,7 +154,7 @@ void Add(NotifyCollectionChangedEventArgs args)
{
var count = args.NewItems.Count;
Count += count;
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);

// Queue up the updates to the UICollectionView
Update(() => CollectionView.InsertItems(CreateIndexesFrom(startIndex, count)), args);
Expand Down Expand Up @@ -185,7 +185,7 @@ void Replace(NotifyCollectionChangedEventArgs args)

if (newCount == args.OldItems.Count)
{
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);

// We are replacing one set of items with a set of equal size; we can do a simple item range update

Expand Down Expand Up @@ -245,22 +245,6 @@ internal object ElementAt(int index)
return -1;
}

internal int IndexOf(object item)
{
if (_itemsSource is IList list)
return list.IndexOf(item);

int count = 0;
foreach (var i in _itemsSource)
{
if (i == item)
return count;
count++;
}

return -1;
}

void Update(Action update, NotifyCollectionChangedEventArgs args)
{
if (CollectionView.Hidden)
Expand Down
Expand Up @@ -149,7 +149,7 @@ void Move(NotifyCollectionChangedEventArgs args)

void Add(NotifyCollectionChangedEventArgs args)
{
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
startIndex = AdjustPositionForHeader(startIndex);
var count = args.NewItems.Count;

Expand Down Expand Up @@ -190,7 +190,7 @@ void Remove(NotifyCollectionChangedEventArgs args)

void Replace(NotifyCollectionChangedEventArgs args)
{
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
startIndex = AdjustPositionForHeader(startIndex);
var newCount = args.NewItems.Count;

Expand Down Expand Up @@ -241,21 +241,5 @@ internal object ElementAt(int index)

return -1;
}

internal int IndexOf(object item)
{
if (_itemsSource is IList list)
return list.IndexOf(item);

int count = 0;
foreach (var i in _itemsSource)
{
if (i == item)
return count;
count++;
}

return -1;
}
}
}
75 changes: 69 additions & 6 deletions src/Core/src/Extensions/EnumerableExtensions.cs
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace Microsoft.Maui
Expand Down Expand Up @@ -35,10 +36,14 @@ public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
foreach (TSource item in enumeration)
{
var group = func(item);
if (!result.ContainsKey(group))
if (!result.TryGetValue(group, out List<TSource>? value))
{
result.Add(group, new List<TSource> { item });
}
else
result[group].Add(item);
{
value.Add(item);
}
}
return result;
}
Expand All @@ -54,19 +59,65 @@ public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
public static int IndexOf<T>(this IEnumerable<T> enumerable, T item)
{
if (enumerable == null)
{
throw new ArgumentNullException(nameof(enumerable));
}

if (enumerable is IList<T> list)
return list.IndexOf(item);
if (enumerable is IList<T> list)
{
return list.IndexOf(item);
}

if (enumerable is T[] array)
return Array.IndexOf(array, item);
if (enumerable is T[] array)
{
return Array.IndexOf(array, item);
}

var i = 0;
foreach (T element in enumerable)
{
if (Equals(element, item))
{
return i;
}

i++;
}

return -1;
}

/// <summary>
/// Find the index of a specific item within the collection.
/// </summary>
/// <param name="enumerable">The collection in which to look for <paramref name="item"/>.</param>
/// <param name="item">The object to be located in this collection.</param>
/// <returns>The index of <paramref name="item"/> in the collection or -1 when the item is not found.</returns>
/// <exception cref="ArgumentNullException">Throws when <paramref name="enumerable"/> is <see langword="null"/>.</exception>
public static int IndexOf(this IEnumerable enumerable, object item)
{
if (enumerable == null)
{
throw new ArgumentNullException(nameof(enumerable));
}

if (enumerable is IList list)
{
return list.IndexOf(item);
}

if (enumerable is Array array)
{
return Array.IndexOf(array, item);
}

var i = 0;
foreach (object element in enumerable)
{
if (Equals(element, item))
{
return i;
}

i++;
}
Expand All @@ -85,11 +136,23 @@ public static int IndexOf<T>(this IEnumerable<T> enumerable, T item)
/// <returns>The index of the first item to match through <paramref name="predicate"/> in the collection or -1 when no match is not found.</returns>
public static int IndexOf<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate)
{
if (enumerable == null)
{
throw new ArgumentNullException(nameof(enumerable));
}

if (enumerable is IList<T> list)
{
return list.IndexOf(predicate);
}

var i = 0;
foreach (T element in enumerable)
{
if (predicate(element))
{
return i;
}

i++;
}
Expand Down
15 changes: 1 addition & 14 deletions src/Core/src/Handlers/Layout/LayoutHandler.Android.cs
Expand Up @@ -119,7 +119,7 @@ void EnsureZIndexOrder(IView child)
}

AView platformChildView = child.ToPlatform(MauiContext!);
var currentIndex = IndexOf(PlatformView, platformChildView);
var currentIndex = PlatformView.IndexOfChild(platformChildView);
symbiogenesis marked this conversation as resolved.
Show resolved Hide resolved

if (currentIndex == -1)
{
Expand All @@ -135,19 +135,6 @@ void EnsureZIndexOrder(IView child)
}
}

static int IndexOf(LayoutViewGroup viewGroup, AView view)
{
for (int n = 0; n < viewGroup.ChildCount; n++)
{
if (viewGroup.GetChildAt(n) == view)
{
return n;
}
}

return -1;
}

public static partial void MapBackground(ILayoutHandler handler, ILayout layout)
{
handler.PlatformView?.UpdateBackground(layout);
Expand Down