Browse Source

Merge pull request #10478 from MrJul/alloc-improvements

Alloc improvements
Max Katz 2 years ago
parent
commit
c2d18117ab

+ 1 - 1
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@@ -225,7 +225,7 @@ public class CompositingRenderer : IRendererWithCompositor
             sortedChildren.Dispose();
         }
         else
-            foreach (var ch in v.GetVisualChildren())
+            foreach (var ch in visualChildren)
             {
                 var compositionChild = ch.CompositionVisual;
                 if (compositionChild != null)

+ 15 - 6
src/Avalonia.Base/StyledElement.cs

@@ -803,8 +803,11 @@ namespace Avalonia
 
             if (theme.HasChildren)
             {
-                foreach (var child in theme.Children)
-                    ApplyStyle(child, null, type);
+                var children = theme.Children;
+                for (var i = 0; i < children.Count; i++)
+                {
+                    ApplyStyle(children[i], null, type);
+                }
             }
         }
 
@@ -816,8 +819,11 @@ namespace Avalonia
             
             if (host.IsStylesInitialized)
             {
-                foreach (var style in host.Styles)
-                    ApplyStyle(style, host, FrameType.Style);
+                var styles = host.Styles;
+                for (var i = 0; i < styles.Count; ++i)
+                {
+                    ApplyStyle(styles[i], host, FrameType.Style);
+                }
             }
         }
 
@@ -826,8 +832,11 @@ namespace Avalonia
             if (style is Style s)
                 s.TryAttach(this, host, type);
 
-            foreach (var child in style.Children)
-                ApplyStyle(child, host, type);
+            var children = style.Children;
+            for (var i = 0; i < children.Count; i++)
+            {
+                ApplyStyle(children[i], host, type);
+            }
         }
 
         private void ReevaluateImplicitTheme()

+ 8 - 5
src/Avalonia.Base/Styling/OrSelector.cs

@@ -71,9 +71,9 @@ namespace Avalonia.Styling
             var activators = new OrActivatorBuilder();
             var neverThisInstance = false;
 
-            foreach (var selector in _selectors)
+            for (var i = 0; i < _selectors.Count; i++)
             {
-                var match = selector.Match(control, parent, subscribe);
+                var match = _selectors[i].Match(control, parent, subscribe);
 
                 switch (match.Result)
                 {
@@ -108,16 +108,19 @@ namespace Avalonia.Styling
 
         internal override void ValidateNestingSelector(bool inControlTheme)
         {
-            foreach (var selector in _selectors)
-                selector.ValidateNestingSelector(inControlTheme);
+            for (var i = 0; i < _selectors.Count; i++)
+            {
+                _selectors[i].ValidateNestingSelector(inControlTheme);
+            }
         }
 
         private Type? EvaluateTargetType()
         {
             Type? result = null;
 
-            foreach (var selector in _selectors)
+            for (var i = 0; i < _selectors.Count; i++)
             {
+                var selector = _selectors[i];
                 if (selector.TargetType == null)
                 {
                     return null;

+ 7 - 8
src/Avalonia.Base/Styling/TypeNameAndClassSelector.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using Avalonia.Controls;
 using Avalonia.Styling.Activators;
 using Avalonia.Utilities;
 
@@ -15,7 +14,7 @@ namespace Avalonia.Styling
     internal class TypeNameAndClassSelector : Selector
     {
         private readonly Selector? _previous;
-        private readonly Lazy<List<string>> _classes = new Lazy<List<string>>(() => new List<string>());
+        private List<string>? _classes;
         private Type? _targetType;
         private string? _selectorString;
 
@@ -81,7 +80,7 @@ namespace Avalonia.Styling
         /// <summary>
         /// The style classes which the selector matches.
         /// </summary>
-        public IList<string> Classes => _classes.Value;
+        public IList<string> Classes => _classes ??= new();
 
         /// <inheritdoc/>
         public override string ToString(Style? owner)
@@ -122,16 +121,16 @@ namespace Avalonia.Styling
                 return SelectorMatch.NeverThisInstance;
             }
 
-            if (_classes.IsValueCreated && _classes.Value.Count > 0)
+            if (_classes is { Count: > 0 })
             {
                 if (subscribe)
                 {
-                    var observable = new StyleClassActivator((Classes)control.Classes, _classes.Value);
+                    var observable = new StyleClassActivator(control.Classes, _classes);
 
                     return new SelectorMatch(observable);
                 }
 
-                if (!StyleClassActivator.AreClassesMatching(control.Classes, Classes))
+                if (!StyleClassActivator.AreClassesMatching(control.Classes, _classes))
                 {
                     return SelectorMatch.NeverThisInstance;
                 }
@@ -172,9 +171,9 @@ namespace Avalonia.Styling
                 builder.Append(Name);
             }
 
-            if (_classes.IsValueCreated && _classes.Value.Count > 0)
+            if (_classes is { Count: > 0 })
             {
-                foreach (var c in Classes)
+                foreach (var c in _classes)
                 {
                     if (!c.StartsWith(":"))
                     {

+ 3 - 7
src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs

@@ -304,13 +304,9 @@ namespace Avalonia.Utilities
             {
                 if (_entryCount == _entries!.Length)
                 {
-                    const double growthFactor = 1.2;
-                    var newSize = (int)(_entryCount * growthFactor);
-
-                    if (newSize == _entryCount)
-                    {
-                        newSize++;
-                    }
+                    var newSize = _entryCount == DefaultInitialCapacity ?
+                        DefaultInitialCapacity * 2 :
+                        (int)(_entryCount * 1.5);
 
                     var destEntries = new Entry[newSize];
 

+ 8 - 8
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
-using System.Linq;
 using System.Reflection;
 using Avalonia.Controls;
 using Avalonia.Data.Core;
@@ -13,13 +12,14 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
 {
     public class CompiledBindingPath
     {
-        private readonly List<ICompiledBindingPathElement> _elements = new List<ICompiledBindingPathElement>();
+        private readonly ICompiledBindingPathElement[] _elements;
 
-        public CompiledBindingPath() { }
+        public CompiledBindingPath()
+            => _elements = Array.Empty<ICompiledBindingPathElement>();
 
-        internal CompiledBindingPath(IEnumerable<ICompiledBindingPathElement> bindingPath, object rawSource)
+        internal CompiledBindingPath(ICompiledBindingPathElement[] elements, object rawSource)
         {
-            _elements = new List<ICompiledBindingPathElement>(bindingPath);
+            _elements = elements;
             RawSource = rawSource;
         }
 
@@ -78,13 +78,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
 
         internal IEnumerable<ICompiledBindingPathElement> Elements => _elements;
 
-        internal SourceMode SourceMode => _elements.OfType<IControlSourceBindingPathElement>().Any()
+        internal SourceMode SourceMode => Array.Exists(_elements, e => e is IControlSourceBindingPathElement)
             ? SourceMode.Control : SourceMode.Data;
 
         internal object RawSource { get; }
 
         public override string ToString()
-            => string.Concat(_elements);
+            => string.Concat((IEnumerable<ICompiledBindingPathElement>) _elements);
     }
 
     public class CompiledBindingPathBuilder
@@ -169,7 +169,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
             return this;
         }
 
-        public CompiledBindingPath Build() => new CompiledBindingPath(_elements, _rawSource);
+        public CompiledBindingPath Build() => new CompiledBindingPath(_elements.ToArray(), _rawSource);
     }
 
     public interface ICompiledBindingPathElement