Tech Off Thread

31 posts

why are gui elements (wpf controls) still so slow?

Back to Forum: Tech Off
  • User profile image
    f-bert

    Hello!

    Today i am asking me why it is not possible to update a System.Windows.Controls.ListView (GridView) 25 times per second. Why need such "simple" operation over 55% of the cpu resources of a 3GHz pentium 4 cpu?
    The displaying works now hardware accelerated. So there is no need to waste so much cpu resourses!
    Some suggestions?

    Best regards,
    Daniel

  • User profile image
    Ion Todirel

    25 times per second? wow, System.Windows.Controls.ListView doesn't have something like BeginUpdate/EndUpdate?

  • User profile image
    troposphere

    It's slow because it's .NET.  It has to check code access permissions, enforce type-safety, perform a criminal background check on you and your family, etc..

  • User profile image
    John Galt

    It's not slow because it's .NET.  The Winforms .NET version of the listview is within 5% of the C++ version. And that's true of essentially every section of the .NET framework including managed DirectX.

    The problem is the WPF is a layer on top of a layer. We're still talking about the same old Windows controls from the dark ages of Windows 3 days that got ported to 32 bit and now to 64 bit.

    Then they owner draw everything.

    End result?  Slow as anything.

    The promise of WPF was a complete decoupled GUI system that had nothing to do with the old tired controls from Windows 3, but instead we got yet another hackup on top of them.

    When is MS going to ditch Win32 and give us new controls that are 100% native and that talk directly to the kernal with nothing in the way? I'm SOOOO tired of Common Controls and everything that they don't do and all of the limitations that they impose (and thus performance problems when you try and make them do things that they weren't designed for).

    Please MS, get a real platform instead of this 1980s technology from hell!

  • User profile image
    littleguru

    If that's true, it is sad. I thought the WPF controls are a complete re-write.

  • User profile image
    W3bbo

    troposphere wrote:
    It's slow because it's .NET.  It has to check code access permissions, enforce type-safety, perform a criminal background check on you and your family, etc..


    IIRC, CAS is performed during JIT, same thing with type-safety. In fact, I'd wager most of the hard work goes on during JIT.

    As for why your WPF app is running slowly, have you tried profiling it first? You'll find most profiling tools can profile Microsoft's own assemblies without difficulty.

  • User profile image
    Frank Hileman

    The interesting thing about the "hardware accelerated" rendering claim is that most bottlenecks in WPF, and in similar frameworks, are not in the rendering, but in the overuse of objects and general algorithm problems. The problems you are seeing in WPF are probably related to layout or text.

  • User profile image
    footballism

    littleguru wrote:
    If that's true, it is sad. I thought the WPF controls are a complete re-write.


        Every WPF controls are brand-new, and completely rewritten, they has nothing do with Win32. you may argue that WPF still use most of the USER features, for instance message pumping(aka Dispatcher), windows message based mouse and keyboard handling, but only the top-level elements such as Window has such knowledge, other controls laid out in this Window has no knowledge of window procedure or window messages, what they really deal with is routed events and routed commands, this level of decoupling from Win32 enables a lot of features such as retained graphics, hardware accelerated UI and control templating which are not available in previous UI framework (such as MFC, or Windows Forms), I think the ability to customize the look of WPF standard controls using data templates and control templates are really awesome. another interesting thing about WPF is that most of the Windows Desktop Manager features in Windows Vista is built on top of umanaged portion of WPF(aka milcore.dll), and most of concepts in WPF are still valid in DWM.

       As to WPF's performance, I think most of the performanace issues with WPF are related to data binding, text rendering, and layout calculation. data binding can be quite slow when data bound to CLR objects, because when binding to CLR objects, WPF uses reflection to set and get the property values of those objects which can be quite slow if your UI are massively bound to CLR objects. another performance bottleneck of WPF is related to layout calculation, layout is the process which can really hang CPU for a long time, because this process involves intensive mathematic calculations, so generally speaking, Grid can be exponentially slow than Canvas, but Grid provides much more richness and flexbility when laying out your UI elements. and text rendering can also be quite slow, this also holds true to other graphical system such as GDI/GDI+.
      So generally speaking, WPF's rendering is really fast, you can test this by simply creating the UI using visual layer programming technique, when you program in the visual layer, most of WPF's features are turned off, such as routed events, layout calculation, and logical tree construction and traversal, and only in this layer, you can actually make a fair judgement of how fast or slow WPF's graphical rendering is.

    Sheva

  • User profile image
    footballism

    troposphere wrote:
    It's slow because it's .NET.  It has to check code access permissions, enforce type-safety, perform a criminal background check on you and your family, etc..


        The process of applying CAS security policy is quite slow, because it by default will walk up the whole call stack, but the this process is turned off most of time if you don't explicitly demand or assert permissions, the enforcement of type-safety I believe are only turned on if you make any late-bound calls or dynamic calls using reflection, or virtual method calls or type castings, becuase those process will always result in the traveral of runtime type information.
        I think most people has some misconceptions of performance. I believe when talking about performance, most guys doesn't understand how fast their code should be or how fast their users want their apps to be, they sorta pursue the optimal performance which is an illusion really.I think what we really need is required performance or desirable performance.

    Sheva

  • User profile image
    footballism

    f-bert wrote:
    Hello!

        Today i am asking me why it is not possible to update a System.Windows.Controls.ListView (GridView) 25 times per second. Why need such "simple" operation over 55% of the cpu resources of a 3GHz pentium 4 cpu?
    The displaying works now hardware accelerated. So there is no need to waste so much cpu resourses!
    Some suggestions?



        ListView in current version of WPF are notoriously quite slow, could you please tell us if you use the VirtualizingStackPanel as the ItemsPanel of your ListView. VirtualizingStackPanel can be exponentially faster than normal StackPanel.
    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ListView>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
    </Page>

    Sheva

  • User profile image
    rhm

    John Galt wrote:
    

    It's not slow because it's .NET.  The Winforms .NET version of the listview is within 5% of the C++ version. And that's true of essentially every section of the .NET framework including managed DirectX.

    The problem is the WPF is a layer on top of a layer. We're still talking about the same old Windows controls from the dark ages of Windows 3 days that got ported to 32 bit and now to 64 bit.

    Then they owner draw everything.

    End result?  Slow as anything.

    The promise of WPF was a complete decoupled GUI system that had nothing to do with the old tired controls from Windows 3, but instead we got yet another hackup on top of them.

    When is MS going to ditch Win32 and give us new controls that are 100% native and that talk directly to the kernal with nothing in the way? I'm SOOOO tired of Common Controls and everything that they don't do and all of the limitations that they impose (and thus performance problems when you try and make them do things that they weren't designed for).

    Please MS, get a real platform instead of this 1980s technology from hell!



    That's just so ignorant and uninformed it's not even funny.

  • User profile image
    MarkPerris

    When is MS going to ditch Win32 and give us new controls that are 100% native and that talk directly to the kernal with nothing in the way


    This is exactly what WPF does!. A lot of the communication is done directly with the kernal, completely avoiding anything Win32. That's the whole point.

    I will agree with you that WPF can be slow. Having done some investigation here, it's often not my Geforce 6200 that's the bottleneck, its actually my 2ghz P4. These are hardly cutting edge, but even so much as scrolling a large block of text can max out the cpu. On the other hand, WPF applications with rotating 3D models can run quite happily at well over 30fps, and appear to be video card limited.

    The 3D composition and rendering engine is actually very fast, the .NET code running on the top can sometimes be slow. Not becuase .NET is slow by nature, it certainly isn't. Just certain controls.

    I know i'll probably get shot down far saying this in a performance related thread, but with CPU's getting faster all the time, and WPF being a 'forward thinking' architecture, i'd rather take the hit and have all the advantages of managed code.

  • User profile image
    jonne

    If a simple list box demand cutting edge CPU and graphics card performance in order to display smoothly, then something has gone very, very wrong in the design process. I yesterday tried out "Avalon patient monitor"-application on wpf.netfx3.com, and I was really surprised at how even just moving the application window was slow, and the animations in the listview were just a joke - to me, the performance was totally unacceptable, and it barely even contained any data. I was under the impression that WPF would be something to look forward to... What a different between all the marketing hype on WPF and reality...

  • User profile image
    f-bert

    Hello all,
    Hello Sheva,

    i dont use ItemsPanelTemplate.

    I want to explain a little bit more what i have done. I have a windows forms application with MDI windows. In such a window i have put a ElementHost Adapter for interop with WPF.
    All my GUI code in the MDI windows will be executed by calling BeginInvoke on the main form from a differnt thread.

    Maybe it will be clearer with example code:

    gridView = new GridView();

    //the next 5 lines i call for 7 times with different values
    gridViewColumn = new GridViewColumn();
    gridViewColumn.Header = "columnHeader";
    Binding binding = new Binding();
    binding.Path = new System.Windows.PropertyPath("myField");
    gridViewColumn.DisplayMemberBinding = binding;
    gridView.Columns.Add(gridViewColumn);

    listView = new ListView();
    listView.View = gridView;

    DockPanel.SetDock(listView, Dock.Top);
    dockPanel = new DockPanel();
    dockPanel.Children.Add(listView);

    elementHost = new ElementHost();
    elementHost.Dock = System.Windows.Forms.DockStyle.Fill;
    elementHost.Child = dockPanel;

    form = new System.Windows.Forms.Form();
    form.Controls.Add(elementHost);

    --> and than i add a generic List for 25 times in the second (List<MyObject> myObjectList;)
    listView.ItemsSource = myObjectList;


    Maybe some hints?

    Best regards,
    Daniel

  • User profile image
    ZippyV

    f-bert wrote:

    --> and than i add a generic List for 25 times in the second (List<MyObject> myObjectList;)
    listView.ItemsSource = myObjectList;


    Maybe some hints?


    Don't refresh your data 25 times per second.

  • User profile image
    footballism

        Resetting the ItemsSouce 25 times per second is not a good way to do it, actually when you want to change the data, you only need to change the data source, you don't need to reset the ItemsSource, but your data source collection should implements INotifyCollectionChanged and INotifyPropertyChanged interface to enable notification of collection change event, and changing the data source from another thread rather than the dispatcher thread is always problematic in current version of WPF, I've made a blog post on how to properly do multi-threaded data binding in WPF:

    DataBinding & Multi-Threading In WPF [Part One]
    DataBinding & Multi-Threading In WPF [Part Two]

    Sheva

  • User profile image
    Rossj

    ZippyV wrote:
    
    f-bert wrote:
    --> and than i add a generic List for 25 times in the second (List<MyObject> myObjectList;)
    listView.ItemsSource = myObjectList;


    Maybe some hints?


    Don't refresh your data 25 times per second.


    Smiley A good point, very well made. Not only setting the ItemSource but also I guess filling up the List as well might be just taking too much time.

    A question I have to ask - do you *really, really* need to update 25 times a second? Is this something that users are likely to notice if you only update say 5 times a second (but still possibly using a different technique - see Sheva's post above).  Personally, and I am thinking without any context here - I probably couldn't intepret changes in data coming at 25 per second unless it is some sort of graph or chart, so why bother showing me data I can't process?

  • User profile image
    rhm

    Rossj wrote:
    
    ZippyV wrote:
    f-bert wrote:
    --> and than i add a generic List for 25 times in the second (List<MyObject> myObjectList;)
    listView.ItemsSource = myObjectList;


    Maybe some hints?


    Don't refresh your data 25 times per second.


    Smiley A good point, very well made. Not only setting the ItemSource but also I guess filling up the List as well might be just taking too much time.

    A question I have to ask - do you *really, really* need to update 25 times a second? Is this something that users are likely to notice if you only update say 5 times a second (but still possibly using a different technique - see Sheva's post above).  Personally, and I am thinking without any context here - I probably couldn't intepret changes in data coming at 25 per second unless it is some sort of graph or chart, so why bother showing me data I can't process?




    Indeed.

    Do you know what happens when you assign a datasource like that?

    The databinding goes throught the collection and looks up the datatemplate for each item. Each datatemplate generates a number of Visuals and usually a few of the very expensive FrameworkElements (if you have buttons or checkboxes or whatever as well as just text). Even if you just have a textblock in the template (the default) it will create a container to put it in. So there's a whole heap of garbage you are creating on the heap for starters.

    Then WPF goes through all those generated elements and lays them out to determine where they will be on screen because unlike win32 controls you are not limited to having each item appear in the same way with WPF. Once those items are layed out it then has to go through and call OnRender() on each and every one to get the low-level drawing primitives for them. That doesn't generate tons of garbage because it uses a bunch of special containers designed for managed and unmanaged use. But it still takes time. Then after all that, the unmaged rendering engine of WPF (called Milcore) goes through the list of drawing commands and actually renders stuff.

    So, err, don't do that 25 times a second if you want a nice responsive app Smiley

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.