缓慢的数据网格 - 提高性能

时间:2016-03-03 12:20:55

标签: c# wpf xaml datagrid

我有一个非常庞大的Datagrid。

这是只有一列的数据网格:

dataset= 
124.0000   81.6900   64.5000  118.0000
 150.0000  103.8400   73.3000  143.0000
   ...
 137.0000   94.9600   67.0000  191.0000
 110.0000   99.7900   75.5000  192.0000
   ...
  94.0000   89.4000   64.5000  139.0000
  74.0000   93.0000   74.0000  148.0000
  89.0000   93.5900   75.5000  179.0000
linLayer = nn.Linear(3,1)
model = nn.Sequential()  
model:add(linLayer)
criterion = nn.MSECriterion()

feval = function(x_new)
    if x ~= x_new then
      x:copy(x_new)
   end
   _nidx_ = (_nidx_ or 0) + 1
   if _nidx_ > (#dataset_inputs)[1] then _nidx_ = 1 end

   local sample = dataset[_nidx_]
   local inputs = sample[{ {2,4} }]
   local target = sample[{ {1} }] 

   dl_dx:zero()

   local loss_x = criterion:forward(model:forward(inputs),target)
   model:backward(inputs, criterion:backward(model.output,target))

   -- return loss(x) and dloss/dx
   return loss_x, dl_dx
end


sgd_params = {
   learningRate = 1e-3,
   learningRateDecay = 1e-4,
   weightDecay = 0,
   momentum = 0
}
epochs = 100


  for i = 1,epochs do
        current_loss = 0
        for i = 1,(#dataset_inputs)[1] do

            _,fs = optim.sgd(feval,x,sgd_params)

            current_loss = current_loss + fs[1]
        end
        current_loss = current_loss / (#dataset_inputs)[1]
        print('epoch = ' .. i .. 
         ' of ' .. epochs .. 
         ' current loss = ' .. current_loss)
    end

And the result:
epoch = 1 of 100 current loss = 8.1958765768632e+138    
epoch = 2 of 100 current loss = 5.0759297005752e+278    
epoch = 3 of 100 current loss = inf 
epoch = 4 of 100 current loss = inf 
epoch = 5 of 100 current loss = nan 
... ...
epoch = 97 of 100 current loss = nan    
epoch = 98 of 100 current loss = nan    
epoch = 99 of 100 current loss = nan    
epoch = 100 of 100 current loss = nan

让我解释一下:

“highlightConverter”检查单元格的值并执行某种语法高亮,语法检查并返回彩色<DataGrid x:Name="dgVarConfig" ItemsSource="{Binding VarConfigList, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Path=SelectedVarConfig, Mode=TwoWay}" Margin="8,56,557,80" AutoGenerateColumns="False" CanUserDeleteRows="False" CanUserResizeRows="False" HeadersVisibility="Column" CanUserAddRows="False" HorizontalScrollBarVisibility="Auto" PreviewKeyDown="dgVarConfig_PreviewKeyDown" BeginningEdit="dgVarConfig_BeginningEdit" CellEditEnding="dgVarConfig_CellEditEnding" SelectionChanged="dgVarConfig_SelectionChanged" EnableRowVirtualization="True" EnableColumnVirtualization="False" VerticalGridLinesBrush="Black" VirtualizingStackPanel.VirtualizationMode ="Standard" VirtualizingStackPanel.IsVirtualizing="true"> <DataGrid.Columns> <DataGridTemplateColumn Width="auto" MinWidth="150" SortMemberPath="Match_expression"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ContentControl> <MultiBinding Converter="{StaticResource highlightConverter}" ConverterParameter="MATCHEXPRESSION"> <Binding Path="Match_expression"></Binding> </MultiBinding> </ContentControl> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate > <DataTemplate> <TextBox Text="{Binding Match_expression}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}" Style="{StaticResource GridTextBox}"></TextBox> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> <DataGridTemplateColumn.HeaderStyle> <Style TargetType="DataGridColumnHeader"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="DataGridColumnHeader"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition Width="auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Grid.Column="1" Padding="5 0" Content="Auswahlformel" VerticalAlignment="Center" Cursor="Hand" Foreground="White"/> <TextBox x:Name="txtMatchExpressionFilter" Margin="0 5" Grid.Column="2" Width="150" Visibility="Collapsed"></TextBox> <Button Grid.Column="3" Margin="5 0" x:Name="btnFilterMatchExpresion" Style="{StaticResource MyButton}" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Right" Click="btnFilterMatchExpresion_Click"> <Button.Background> <ImageBrush ImageSource="Resources/filter.png"/> </Button.Background> </Button> <Path x:Name="SortArrow" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center" Width="8" Height="6" Margin="2,0,5,0" Stretch="Fill" Opacity="0.5" Fill="White" RenderTransformOrigin="0.5,0.4" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" /> <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="4" HorizontalAlignment="Right" Width="1" BorderThickness="1" BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" Cursor="SizeWE"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="SortDirection" Value="Ascending"> <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> <Setter TargetName="SortArrow" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="180" /> </Setter.Value> </Setter> </Trigger> <Trigger Property="SortDirection" Value="Descending"> <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </DataGridTemplateColumn.HeaderStyle> </DataGridTemplateColumn> </DataGrid.Columns> <DataGrid.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <StackPanel Background="Gray" Margin="-5 0 0 0"> <TextBlock Foreground="White" FontWeight="Bold" Text="{Binding Path=Name, StringFormat=Gruppe: {0}}" Margin="10 5 0 5"/> <ItemsPresenter /> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <DockPanel Background="LightGray"> <TextBlock Text="{Binding Path=Name}" Foreground="Black" Margin="10 2 0 2"/> <ItemsPresenter></ItemsPresenter> </DockPanel> </DataTemplate> </GroupStyle.HeaderTemplate> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.ContextMenu> <ContextMenu> <MenuItem x:Name="cmAddGroup" Header="Gruppe zuweisen" Click="cmAddGroup_Click" ></MenuItem> <MenuItem x:Name="cmRemoveDeleteFlag" Header="Löschvermerk entfernen" Click="cmRemoveDeleteFlag_Click"></MenuItem> </ContextMenu> </DataGrid.ContextMenu>

如果我要修改TextBlock我必须将其转换为TextBlock

网格有两组(我没有发布所有列,所以这些组不在这里,但是TextBox

我们在这里添加了两个SortingArrows。 在每个列Header上都有一个filterButton来过滤行。

这引出了我的问题:网格在过滤,排序,调整行/列大小,重新排序列,滚动等方面变得非常慢。 我认为这是因为GroupStyleTextBlock项目。有没有更好的解决方案来改善性能?

这是HighlightConverter.cs

TextBox

2 个答案:

答案 0 :(得分:2)

在我看来,这不是使用IMultiConverter,而是VirtualizationColumn Rendering的问题。

尝试将这些属性用于DataGrid:

  • 为网格启用VirtualizingStackPanel.VirtualizationMode
  • 设置VirtualizingStackPanel.IsVirtualizing =&#34; true&#34; for DataGrid
  • MaxWidth =&#34; 2560&#34; MaxHeight =&#34; 1600&#34;

Never put a DataGrid in a ScrollViewer, because you will essentially lose virtualization

例如:

<DataGrid ItemsSource="{Binding EmployeeDataTable, IsAsync=True}" 
          VirtualizingStackPanel.IsVirtualizing="true" EnableRowVirtualization="True"
        EnableColumnVirtualization="True" MaxWidth="2560" MaxHeight="1600"  
        VirtualizingStackPanel.VirtualizationMode="Recycling"   
        VirtualizingPanel.IsVirtualizingWhenGrouping="True"/>

答案 1 :(得分:1)

你有相当大的Convert方法。想象一下,它会调用DataGrid中的每个单元格。

  1. 尝试将语法分析转到另一个线程。对于用户来说,它看起来像 - 输入文本,并且会在几秒钟内检查和/或突出显示语法。

  2. Regex.Matches使用延迟初始化,因此当您迭代匹配时 - 它实际上每次都基于正则表达式在字符串中执行搜索。尝试排除assignColor中的Convert()方法组并检查执行时间。如果有帮助 - 尝试编写自己的字符串解析器,而不使用正则表达式。

  3. 在此行List<Char> splittedInput = input.ToCharArray().ToList();中,您将通过input个字符进行两次迭代。第一次 - 从字符串字符创建数组时,第二次 - 从数组项创建列表时。然后,您将在foreach (Char character in splittedInput)中再次遍历此字符串。您实际上可以遍历input本身:foreach (var character in input)

  4. 在这一行中:if (values.Count() == 2)使用.Length(数组的属性)而不是.Count()(扩展LINQ方法),因为在每个时刻数组都知道它&#39 ; s长度,调用扩展linq方法导致处理类似于IEnumerable的数组,并进行延迟初始化。

  5. 但在我看来,主要问题在于连续的文本分析。频繁的解决方案是在并行线程中执行字符串分析 - 用于非暂停用户输入(或对此执行任何操作)。