开发者

Speed of Color Resolution in XAML (Silverlight)

Is there anyway to speed-test which of the following resolve faster in XAML for colors:

Named Color: Orange
Hex: #ff6600
Shorthand Hex: #f60
Known Color: DarkOrange

This is not just a curiosity or an academic exercise. I have tons and tons of animations and colors that change colors many many times, on a large scale. I need to ee开发者_如何转开发k out ever bit of time-saving I can.

Looking for a way to test the above against each other for Silverlight. Any ideas?


I couldn't think of a definitive way to test this, but I put something together that may give you a hint. Effectively, I bound the color of a rectangle to a (string) SelectedColor property of a class that raised the PropertyChanged event every time it changed. Then I created four different List collections that had colors defined in all the different ways that you described, and in a background thread looped through them each some 10000 times, setting the SelectedColor property on each loop by dispatching to back to the UI thread. The complicated part was just keeping all the threads synchronized properly, and there's at least one hack in there where I loop every 20 ms until I saw that the previous task had finished. But it at least forces the UI thread to parse a color string, which is presumably what you're interested in.

At any rate, to the extent that this testing methodology is valid, it looks like using the "hex" notation is perhaps slightly faster than the others, though not by much. The average results on my machine after 10 test runs:

Hex: 4596 ms
Named: 4609 ms
Shorthand Hex: 5018 ms
Known Colors: 5065 ms

Just for reference, here's the code-behind:

public partial class MainPage : UserControl, INotifyPropertyChanged
{
    public MainPage()
    {
        InitializeComponent();

        namedColors.Add("Black");
        namedColors.Add("Black");
        namedColors.Add("Brown");
        namedColors.Add("Cyan");
        namedColors.Add("DarkGray");
        namedColors.Add("Gray");
        namedColors.Add("Green");
        namedColors.Add("LightGray");
        namedColors.Add("Magenta");
        namedColors.Add("Orange");

        hexColors.Add(Colors.Black.ToString());
        hexColors.Add(Colors.Black.ToString());
        hexColors.Add(Colors.Brown.ToString());
        hexColors.Add(Colors.Cyan.ToString());
        hexColors.Add(Colors.DarkGray.ToString());
        hexColors.Add(Colors.Gray.ToString());
        hexColors.Add(Colors.Green.ToString());
        hexColors.Add(Colors.LightGray.ToString());
        hexColors.Add(Colors.Magenta.ToString());
        hexColors.Add(Colors.Orange.ToString());

        knownColors.Add("LawnGreen");
        knownColors.Add("LemonChiffon");
        knownColors.Add("LightBlue");
        knownColors.Add("LightCoral");
        knownColors.Add("LightCyan");
        knownColors.Add("LightGoldenrodYellow");
        knownColors.Add("LightGray");
        knownColors.Add("LightGreen");
        knownColors.Add("LightPink");
        knownColors.Add("LightSalmon");

        shorthandHexColors.Add("#000");
        shorthandHexColors.Add("#111");
        shorthandHexColors.Add("#222");
        shorthandHexColors.Add("#333");
        shorthandHexColors.Add("#444");
        shorthandHexColors.Add("#555");
        shorthandHexColors.Add("#666");
        shorthandHexColors.Add("#777");
        shorthandHexColors.Add("#aaa");
        shorthandHexColors.Add("#bbb");

        LayoutRoot.DataContext = this;
    }

    private List<string> namedColors = new List<string>();
    private List<string> hexColors = new List<string>();
    private List<string> shorthandHexColors = new List<string>();
    private List<string> knownColors = new List<string>();

    private List<double> namedColorDurations = new List<double>();
    private List<double> hexColorDurations = new List<double>();
    private List<double> shorthandHexColorDurations = new List<double>();
    private List<double> knownColorDurations = new List<double>();

    private string selectedColor;
    public string SelectedColor
    {
        get
        {
            return selectedColor;
        }
        set
        {
            if (selectedColor != value)
            {
                selectedColor = value;
                RaisePropertyChanged("SelectedColor");
            }
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private bool isTesting = false;
    private void testButton_Click(object sender, RoutedEventArgs e)
    {
        if (isTesting)
        {
            return;
        }
        else
        {
            isTesting = true;
        }
        ThreadPool.QueueUserWorkItem(o =>
        {
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            for (int i = 0; i < 10; i++)
            {
                TestColors(resetEvent, hexColors, lstHexColorDuration, hexColorDurations);
                resetEvent.WaitOne();
                TestColors(resetEvent, namedColors, lstNamedColorDuration, namedColorDurations);
                resetEvent.WaitOne();
                TestColors(resetEvent, shorthandHexColors, lstShorthandHexDuration, shorthandHexColorDurations);
                resetEvent.WaitOne();
                TestColors(resetEvent, knownColors, lstKnownColorDuration, knownColorDurations);
                resetEvent.WaitOne();
            }
            Dispatcher.BeginInvoke(() =>
            {
                lstHexColorDuration.Items.Add(hexColorDurations.Average().ToString());
                lstNamedColorDuration.Items.Add(namedColorDurations.Average().ToString());
                lstShorthandHexDuration.Items.Add(shorthandHexColorDurations.Average().ToString());
                lstKnownColorDuration.Items.Add(knownColorDurations.Average().ToString());
            });
            isTesting = false;
        });
    }

    private int testsFinished = 0;
    private void TestColors(AutoResetEvent resetEvent, List<string> colorList, ListBox resultListBox, List<double> results)
    {
        ThreadPool.QueueUserWorkItem(o =>
            {
                var start = DateTime.Now;
                int testPasses = 10000;
                testsFinished = 0;
                for (int i = 0; i < testPasses; i++)
                {
                    foreach (string color in colorList)
                    {
                        SetColor(color);
                    }
                }
                while (testsFinished < testPasses * colorList.Count)
                {
                    Thread.Sleep(20);
                }
                DateTime finish = DateTime.Now;
                results.Add((finish - start).TotalMilliseconds);
                Dispatcher.BeginInvoke(() => resultListBox.Items.Add((DateTime.Now - start).ToString()));
                resetEvent.Set();
            });
    }

    private void SetColor(string color)
    {
        Dispatcher.BeginInvoke(() =>
            {
                SelectedColor = color;
                Interlocked.Increment(ref testsFinished);
            });
    }
}

And here's the XAML proper:

<UserControl 
x:Class="SilverlightScratch.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SilverlightScratch"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500">

<Grid x:Name="LayoutRoot" Background="White" >
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Button Height="30" Width="100" x:Name="testButton" Content="Start Test" Click="testButton_Click" />
    <Rectangle Height="30" Width="100" Fill="{Binding SelectedColor}" Grid.Row="2" />
    <StackPanel Orientation="Horizontal" Grid.Row="1">
        <StackPanel>
            <TextBlock Text="Named Color Duration" />
            <ListBox x:Name="lstNamedColorDuration" />
        </StackPanel>
        <StackPanel>
            <TextBlock Text="Hex Color Duration" />
            <ListBox x:Name="lstHexColorDuration" />
        </StackPanel>
        <StackPanel>
            <TextBlock Text="Shorthand Hex Duration" />
            <ListBox x:Name="lstShorthandHexDuration" />
        </StackPanel>
        <StackPanel>
            <TextBlock Text="Known Colors Duration" />
            <ListBox x:Name="lstKnownColorDuration" />
        </StackPanel>
    </StackPanel>
</Grid>
</UserControl>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜