Sunday, August 16, 2009

Enumerating sequential containers in C#

Here I’ve posted my performance comparison when it’s simply needed to enumerate a sequential array. I calculated control sum on all elements. In the first table array element is value-type, in the second – reference-type. I used very long arrays, however I believe it makes sense when you really need to speed up your code and array length is greater than 1000 elements.






int[]List<int>Collection<int>
for0,1050,160,297
foreach0,1720,340,551
IEnumerator11,5620,8830,937
Linq0,7070,9021,219







Int[]List<Int>Collection<Int>
for0,2380,2970,395
foreach0,230,4020,785
IEnumerator2,7340,860,875
Linq0,751,2581,543

avoid IEnumerator at all IEnumerator gave the unexpected result; it will be the bad idea to use it in a performance critical code and to use it all in comparison with another simpler syntaxes.
Collection or its descendants are not intended to improve performance I knew that before the test and here I’ve asserted it. Better to use it on upper abstraction level to bind interfaces and not in local or class scopes at all.
foreach slowed down performance myth is busted I supposed that foreach with its type casting at every turn will slow down performance. However it’s not. Moreover if iEnd index local variable is not used and at every turn array.Length or list.Count dereference occurs, for cycle results will be worse than the posted here. So in most real cases I can’t mark out for or foreach cycle. They both are good.
array[] is a little bit faster than List<>
Linq - I expected better results However I can’t give the conclusion about Linq here. Additional research is required.

Sunday, July 12, 2009

C# 3.0 and WPF programming style

Today I’m going to talk about c# language and .net framework. In fact, the platform becomes more popular from year to year. In spite of negative labels, which c# embodies, one of them for instance says: something that has been done with c# is in rough and ready fashion :), c# brings really worth features for professional long term development. More features came with .net 3.0 and c# 3.0 (.net 3.5).
Here I want to explain the global code writing strategies I adhere, and which IMHO implement more efficient, robust solutions using c# 3.0 and WPF.

Event-driven approach



Consider next example:

class Class1
{
private List<int> _collection;
private int _sum = 0;
public int Sum { get { return _sum; } }

public Class1()
{
_collection = new List<int>();
}

public void Add(int value)
{
_collection.Add(value);
_sum += value;
}
}

class Class2
{
private ObservableCollection<int> _collection;
private int _sum = 0;
public int Sum { get { return _sum; } }

public Class2()
{
_collection = new ObservableCollection<int>();
_collection.CollectionChanged += _collection_CollectionChanged;
}

public void Add(int value)
{
_collection.Add(value);
}

private void _collection_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
for (int i = 0; i < e.NewItems.Count; i++)
_sum += (int)e.NewItems[i];
}
}

Both classes hold a collection of values and a field that depend on the collection contents. The field should not be calculated each time when its value is used due to performance reasons – on default a field is accessed more often when a collection is changed and an operation of recalculating costs. So the efficient way here is to track collection changes. The example simplified as possible – instead of sum a field or its dependency from a collection can be more complex. So the task is real, and there are two solutions here. The first style I name classic object-oriented approach, the second - event-driven approach. Both approaches are wide-spread in c#. Consider pluses and minuses right now.
On the first look it makes sense that 2nd approach is better. You will never forget about updating a dependency field because it occurs in one place and looks clear. However there are a lot of consequences here. In fact, a collection is responsible now for a class field, not a class itself. Essentially this means that a class and its internal collection are highly coupled and it violates object-oriented crucial design principle – component modularity. Secondly, code workflow became unobvious – call stack is broken. Thirdly, extensibility is lame. If such module becomes more complex it will be harder to update it, because we have high coupling and vague workflow.
Trying to be objective I must say that the 1st approach is preferable.

Property ambiguity



class ValueHolder
{
public int Value { get; set; }
}
class ClassWithProperty
{
private ValueHolder _value;
public ValueHolder Value
{
get
{
if (_value == null)
_value = new ValueHolder();
return _value;
}
set
{
_value = value;
if (_value.Value < 0)
_value.Value = 0;
}
}

public void DoSomeStuff()
{
//ambiguity to use Value or _value ?
}
}

Here the public property and the private field have the same meaning, but however are different in usage. While a code will grow it is important to resolve this ambiguity. The code should be refactored to:

class ValueHolder
{
private int _value;
public int Value
{
get { return _value; }
set
{
_value = value;
if (_value < 0)
_value = 0;
}
}
}
class ClassWithProperty
{
private ValueHolder _value = new ValueHolder();
public ValueHolder Value
{
get { return _value; }
set { _value = value; }
}

public void DoSomeStuff()
{
//Value or _value
}
}

So property is the good way to add extra emerging logic to an exposing field, but the better way is not to abuse this feature (except the cases when a property exposes a field with a slightly or considerably different meaning).

Considered stuff belongs to any version of c#. Next part is devoted to modern c# 3.0 and WPF.

XAML and ViewModel pattern



Exposing BAL classes to GUI is the known problem of mixing and messing them with GUI entities. WPF gives the trendy solution – ViewModel pattern (Model-View-ViewModel or MVVM). Here you can find the explanation of pattern
Again the idea is that you build up ViewModel classes which expose future displaying entities. In other words you build up abstract view (its data context) or model extended for presentation. Next step is xaml with its binding and commands which make ViewModel attaching easy. XAML also has other profits; it enables rapid View creating/maintaining and leads to minimal code in xaml.cs files.

MVVM example


On the left side there is editable data grid, on the right saving data. It looks like working with an xml file in WPF, however it does not. In the example there is extendable MVVM, which connects left and right parts in some common manner.


The Model simply holds the cars collection, the operations on it and the xml features.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;


namespace WPFExample
{
public class CarsModel
{
public class Car
{
public Car()
{
Year = DateTime.Now.Year;
Color = "255,0,0,0";
}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Year { get; set; }
public string Color { get; set; }
}

public CarsModel()
{
_xml = @"
<Cars>
<Car>
<Id>1</Id>
<Name>Volvo 850</Name>
<Description>car details</Description>
<Year>1994</Year>
<Color>255,0,0,0</Color>
</Car>
<Car>
<Id>2</Id>
<Name>Opel Vectra</Name>
<Description>details</Description>
<Year>1999</Year>
<Color>255, 212, 208, 200 </Color>
</Car>
</Cars>
";
XDocument document = XDocument.Load(new StringReader(_xml));
_cars = (from car in document.Descendants("Car")
select new Car
{
Id = (int)car.Element("Id"),
Name = (string)car.Element("Name"),
Description = (string)car.Element("Description"),
Year = (int)car.Element("Year"),
Color = (string)car.Element("Color"),
}).ToList();
_lastId = (from car in _cars select car.Id).Max();

UpdateXml();
}

private int _lastId;
private readonly List<Car> _cars;
private string _xml;

public List<Car> Cars
{
get { return _cars; }
}

public string Xml
{
get { return _xml; }
}

public void UpdateXml()
{
_xml = new XElement("Cars",
from car in _cars
select new XElement("Car",
new XElement("Id", car.Id),
new XElement("Name", car.Name),
new XElement("Description", car.Description),
new XElement("Year", car.Year),
new XElement("Color", car.Color))).ToString();
}

public void Insert(Car car)
{
car.Id = ++_lastId;
_cars.Add(car);
}

public void Update(Car car)
{
Car internalCar = _cars.Find(c => c.Id == car.Id);
if (internalCar != null)
{
internalCar.Name = car.Name;
internalCar.Description = car.Description;
internalCar.Year = car.Year;
internalCar.Color = car.Color;
}
}

public void Delete(Car car)
{
_cars.RemoveAll(c => c.Id == car.Id);
}
}
}


The CarsViewModel and CarViewModel constructors initialize all data and commands at once. It became possible through the Delegate Command feature from Composite WPF library. Make attention on the constructors again – they require handlers – I think it’s very powerful approach to show both data and actions a ViewModel presents.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ComponentModel;
using System.Windows.Media;
using Microsoft.Practices.Composite.Wpf.Commands;
using System.Windows;
using System.Collections.Specialized;


namespace WPFExample
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public delegate string CarHandler(CarsModel.Car car);

public class CarsViewModel : ViewModel
{
public CarsViewModel(
IEnumerable<CarsModel.Car> cars,
string xml,
CarHandler insertCarHandler,
CarHandler updateCarHandler,
CarHandler deleteCarHandler)
{
_cars = new ObservableCollection<CarViewModel>(
(from car in cars
select new CarViewModel(car, (c) =>
{
Xml = updateCarHandler(c);
return Xml;
})).ToList());
_cars.CollectionChanged += (o, e) =>
{
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (CarViewModel car in e.OldItems)
{
Xml = deleteCarHandler((CarsModel.Car)car);
}
}
};

Xml = xml;


Copy = new DelegateCommand<object>(
(o) =>
{
Clipboard.SetText(Xml);
});
Insert = new DelegateCommand<object>(
(o) =>
{
CarsModel.Car car = new CarsModel.Car();
Xml = insertCarHandler(car);
CarViewModel carViewModel = new CarViewModel(car, (c) =>
{
Xml = updateCarHandler(c);
return Xml;
});
_cars.Add(carViewModel);
});
Delete = new DelegateCommand<object>(
(o) =>
{
if (SelectedCars != null)
{
IList deletionList = new List<CarViewModel>(
SelectedCars.Cast<CarViewModel>());
foreach (CarViewModel car in deletionList)
{
_cars.Remove(car);
Xml = deleteCarHandler((CarsModel.Car)car);
}
}
},
(o) =>
{
return _selectedCars != null && _selectedCars.Count > 0;
});

_years = new List<int>();
for (int i = 1970; i <= DateTime.Now.Year; i++)
_years.Add(i);
}

private readonly ObservableCollection<CarViewModel> _cars;
public ObservableCollection<CarViewModel> Cars { get { return _cars; } }

private IList _selectedCars;
public IList SelectedCars
{
get { return _selectedCars; }
set
{
_selectedCars = value;
Delete.RaiseCanExecuteChanged();
}
}

public DelegateCommand<object> Copy { get; set; }
public DelegateCommand<object> Insert { get; set; }
public DelegateCommand<object> Delete { get; set; }

private string _xml;
public string Xml
{
get { return _xml; }
private set
{
_xml = value;
NotifyPropertyChanged("Xml");
}
}

private readonly List<int> _years;
public List<int> Years { get { return _years; } }

public class CarViewModel : ViewModel
{
public int Id { get; set; }
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
private string _description;
public string Description
{
get { return _description; }
set
{
_description = value;
NotifyPropertyChanged("Description");
}
}
private int _year;
public int Year
{
get { return _year; }
set
{
_year = value;
NotifyPropertyChanged("Year");
}
}
private Color _color;
public Color Color
{
get { return _color; }
set
{
_color = value;
NotifyPropertyChanged("Color");
}
}
public byte ColorR
{
get { return _color.R; }
set
{
_color.R = value;
NotifyPropertyChanged("Color");
}
}
public byte ColorG
{
get { return _color.G; }
set
{
_color.G = value;
NotifyPropertyChanged("Color");
}
}
public byte ColorB
{
get { return _color.B; }
set
{
_color.B = value;
NotifyPropertyChanged("Color");
}
}
public string ColorSortableString
{
get { return string.Format("{0:x2}{1:x2}{2:x2}", _color.R, _color.G, _color.B); }
}

public CarViewModel(
CarsModel.Car car,
CarHandler updateCarHandler)
{
Id = car.Id;
Name = car.Name;
Description = car.Description;
Year = car.Year;
string[] bytes = car.Color.Split(',');
Color = Color.FromArgb(byte.Parse(bytes[0]), byte.Parse(bytes[1]), byte.Parse(bytes[2]), byte.Parse(bytes[3]));
PropertyChanged += (o, e) =>
{
updateCarHandler((CarsModel.Car)this);
};
}

public static explicit operator CarsModel.Car(CarViewModel car)
{
return new CarsModel.Car
{
Id = car.Id,
Name = car.Name,
Description = car.Description,
Year = car.Year,
Color = string.Format("{0},{1},{2},{3}", car.Color.A, car.Color.R, car.Color.G, car.Color.B),
};
}
}

public enum ColumnType
{
String,
Year,
Color,
}

public class ColumnDefinition
{
public string Name { get; set; }
public string Path { get; set; }
public string SortMemberPath { get; set; }
public ColumnType Type { get; set; }
}

public ColumnDefinition[] Columns
{
get
{
var columns = new List<ColumnDefinition>
{
new ColumnDefinition
{
Name = "Title",
Path = "Name",
SortMemberPath = "Name",
Type = ColumnType.String,
},
new ColumnDefinition
{
Name = "Description",
Path = "Description",
SortMemberPath = "Description",
Type = ColumnType.String,
},
new ColumnDefinition
{
Name = "Year",
Path = "Year",
SortMemberPath = "Year",
Type = ColumnType.Year,
},
new ColumnDefinition
{
Name = "Color",
Path = "Color",
SortMemberPath = "ColorSortableString",
Type = ColumnType.Color,
}
};
return columns.ToArray();
}
}
}
}


XAML presents the View structure.

<Window x:Class="WPFExample.CarsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit"
xmlns:local="clr-namespace:WPFExample"
xmlns:mvvm="clr-namespace:MVVm.Core.View;assembly=MVVm.Core"
Title="Cars View" Width="900" Height="600">
<Window.Resources>
<mvvm:CommandReference x:Key="Insert" Command="{Binding Insert}"/>
</Window.Resources>
<Window.InputBindings>
<KeyBinding Command="{StaticResource Insert}" Key="Insert"/>
</Window.InputBindings>
<Grid x:Name="LayoutRoot">
<Grid.Resources>
<local:BrushConverter x:Key="BrushConverter"/>
<DataTemplate x:Key="StringCell" DataType="String">
<TextBlock Text="{Binding Path}"/>
</DataTemplate>
<DataTemplate x:Key="StringCellEditing" DataType="String">
<TextBox Text="{Binding Path, Mode=TwoWay}"/>
</DataTemplate>
<DataTemplate x:Key="YearCell" DataType="Year">
<TextBlock/>
</DataTemplate>
<DataTemplate x:Key="YearCellEditing" DataType="Year">
<ComboBox ItemsSource="{Binding Path=DataContext.Years,
RelativeSource={RelativeSource AncestorType={x:Type toolkit:DataGrid}}}"
SelectedItem="{Binding Path, Mode=TwoWay}"/>
</DataTemplate>
<DataTemplate x:Key="ColorCell" DataType="Color">
<Border Background="{Binding Path, Converter={StaticResource BrushConverter}}"/>
</DataTemplate>
<DataTemplate x:Key="ColorCellEditing" DataType="Color">
<Border Background="{Binding Path, Converter={StaticResource BrushConverter}}">
<StackPanel Orientation="Vertical">
<Slider Value="{Binding Path, Mode=TwoWay}"
Minimum="0" Maximum="255"/>
<Slider Value="{Binding Path, Mode=TwoWay}"
Minimum="0" Maximum="255"/>
<Slider Value="{Binding Path, Mode=TwoWay}"
Minimum="0" Maximum="255"/>
</StackPanel>
</Border>
</DataTemplate>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical">
<toolkit:DataGrid x:Name="_dataGrid" ItemsSource="{Binding Cars}"
AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="True">
</toolkit:DataGrid>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding Insert}" Content="+"
Margin="5,5,0,0" Padding="3,3,3,3"/>
<Button Command="{Binding Delete}" Content="-"
Margin="5,5,0,0" Padding="3,3,3,3"/>
</StackPanel>
</StackPanel>
<Grid Grid.Column="1" Margin="1,1,1,1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="Blue" BorderThickness="2" Grid.RowSpan="2"/>
<Button Command="{Binding Copy}" Content="Copy To Buffer"/>
<ScrollViewer Grid.Row="1">
<TextBlock Text="{Binding Xml}"/>
</ScrollViewer>
</Grid>
</Grid>
</Window>


The View code does developer-defined dynamic data grid initialization. It’s rather complex feature, however I didn’t want to do a simple example. There is only one callback in the View code that refreshes data grid selected rows in the ViewModel. The data grid control is from WPF Toolkit. I’m sure that with another or own control implementation and with other XAML extensions like binding delegates to built-in commands it will be possible to rid from the View code at all.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Microsoft.Windows.Controls;
using System.Windows.Input;

namespace WPFExample
{
public partial class CarsView : Window
{
public CarsView()
{
InitializeComponent();

DataContextChanged += (o, e) =>
{
_dataGrid.Columns.Clear();

Bind(this, ApplicationCommands.Delete, (DataContext as CarsViewModel).Delete);
Bind(this, ApplicationCommands.Copy, (DataContext as CarsViewModel).Copy);

foreach (CarsViewModel.ColumnDefinition columnDefinition in
(DataContext as CarsViewModel).Columns)
{
DataGridColumn column = CreateColumn(columnDefinition);
if (column != null)
_dataGrid.Columns.Add(column);
}

_dataGrid.SelectionChanged += (ob, ea) =>
{
(DataContext as CarsViewModel).SelectedCars = _dataGrid.SelectedItems;
};
};
}

static private void Bind(UIElement element, ICommand command, ICommand targetCommand)
{
element.CommandBindings.Add(new CommandBinding(command,
(o, e) =>
{
targetCommand.Execute(e.Parameter);
},
(o, e) =>
{
e.CanExecute = targetCommand.CanExecute(e.Parameter);
}));
}

private DataGridColumn CreateColumn(CarsViewModel.ColumnDefinition columnDefinition)
{
DataGridTemplateColumnWithBindingPath column = null;
switch (columnDefinition.Type)
{
case CarsViewModel.ColumnType.String:
column = new DataGridTemplateColumnWithBindingPath
{
CellTemplate = LayoutRoot.Resources["StringCell"] as DataTemplate,
CellEditingTemplate = LayoutRoot.Resources["StringCellEditing"] as DataTemplate,
};
break;
case CarsViewModel.ColumnType.Year:
column = new DataGridTemplateColumnWithBindingPath
{
CellTemplate = LayoutRoot.Resources["YearCell"] as DataTemplate,
CellEditingTemplate = LayoutRoot.Resources["YearCellEditing"] as DataTemplate,
};
break;
case CarsViewModel.ColumnType.Color:
column = new DataGridTemplateColumnWithBindingPath
{
CellTemplate = LayoutRoot.Resources["ColorCell"] as DataTemplate,
CellEditingTemplate = LayoutRoot.Resources["ColorCellEditing"] as DataTemplate,
};
break;
}

if (column != null)
{
column.Header = columnDefinition.Name;
column.CanUserReorder = true;
column.CanUserSort = true;
column.SortMemberPath = columnDefinition.SortMemberPath;
column.BindingPath = columnDefinition.Path;
}
return column;
}
}


public class DataGridTemplateColumnWithBindingPath : DataGridTemplateColumn
{
public string BindingPath
{
get { return (string)GetValue(BindingProperty); }
set { SetValue(BindingProperty, value); }
}
public static readonly DependencyProperty BindingProperty = DependencyProperty.Register(
"BindingPath", typeof(string), typeof(DataGridTemplateColumnWithBindingPath));

protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
FrameworkElement element = base.GenerateEditingElement(cell, dataItem);
element.ApplyTemplate();
SetEditingBindingPath(VisualTreeHelper.GetChild(element, 0));
return element;
}
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
FrameworkElement element = base.GenerateElement(cell, dataItem);
element.ApplyTemplate();
SetBindingPath(VisualTreeHelper.GetChild(element, 0));
return element;
}

private void SetEditingBindingPath(object bindingElement)
{
string dataType = (string)CellEditingTemplate.DataType;
if (dataType == "String")
{
ResetBindingWithNewPath(bindingElement as TextBox,
TextBox.TextProperty, BindingPath);
}
else if (dataType == "Year")
{
ResetBindingWithNewPath(bindingElement as ComboBox,
ComboBox.SelectedItemProperty, BindingPath);
}
else if (dataType == "Color")
{
Border border = bindingElement as Border;
ResetBindingWithNewPath(border, Border.BackgroundProperty, BindingPath);
ResetBindingWithNewPath(((border.Child as StackPanel).Children[0]
as Slider), Slider.ValueProperty, BindingPath + "R");
ResetBindingWithNewPath(((border.Child as StackPanel).Children[1]
as Slider), Slider.ValueProperty, BindingPath + "G");
ResetBindingWithNewPath(((border.Child as StackPanel).Children[2]
as Slider), Slider.ValueProperty, BindingPath + "B");
}
}

private void SetBindingPath(object bindingElement)
{
string dataType = (string)CellTemplate.DataType;
if (dataType == "String" || dataType == "Year")
{
ResetBindingWithNewPath(bindingElement as TextBlock,
TextBlock.TextProperty, BindingPath);
}
else if (dataType == "Color")
{
ResetBindingWithNewPath(bindingElement as Border,
Border.BackgroundProperty, BindingPath);
}
}

private static void ResetBindingWithNewPath(
FrameworkElement element,
DependencyProperty property,
string newPath)
{
BindingExpression binding = element.GetBindingExpression(property);
element.SetBinding(property,
new Binding
{
Path = new PropertyPath(newPath),
Mode = binding != null ? binding.ParentBinding.Mode : BindingMode.Default,
Converter = binding != null ? binding.ParentBinding.Converter : null,
ConverterParameter = binding != null ? binding.ParentBinding.ConverterParameter : null,
});
}
}

public class BrushConverter : IValueConverter
{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new SolidColorBrush((Color)value);
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

#endregion
}
}


Finally here is the application initialization.

CarsModel model = new CarsModel();
CarsViewModel viewModel = new CarsViewModel(
model.Cars,
model.Xml,
(c) => { model.Insert(c); model.UpdateXml(); return model.Xml; },
(c) => { model.Update(c); model.UpdateXml(); return model.Xml; },
(c) => { model.Delete(c); model.UpdateXml(); return model.Xml; });
CarsView view = new CarsView { DataContext = viewModel };
view.Show();


Anonymous methods and lambda expressions



Writing callbacks always annoys me. It needs extra time for documenting/marking. Reading callbacks causes a reader leaping through different part of code while statements inside a callback should be read together with the callback usage statements. Since C# 2.0 there is the solution (anonymous methods) that lets to do inline callback implementation. C# 3.0 introduced lambda expressions - new simpler syntax. However anonymous methods can be still in use, because they have some features that lambda expressions have not. In practice all callbacks becomes inline and in rare cases, when similar callbacks contains the same code, this code should be a candidate for normally introduced method.
In the last example you can find usage of lambdas.

Deeper in MVVM



MVVM didn’t appear suddenly. Heretofore there were similar MVC (Model-View-Controller), MVP (Model-View-Presenter) patterns, which are not simple code-behind. Also data binding feature in ASP.NET looks like XAML binding. However there are two points which excel MVVM among all ancestors.
First is that de facto MVVM has language native support – there are no third-parties, plug-in classes and namespaces - no interfaces you should learn first. But of course you should be aware of XAML (the key to this support) and however learn a couple of interfaces. One of them is INotifyPropertyChanged interface, which always ought to be implemented in a ViewModel. It creates and routes developer-defined updating notifications to WPF internal engine. ObservableCollection and its descendants also have similar purpose - describing more complex data structure to WPF internal. There is no necessity to use it outside WPF.
Second point belongs to desktop and desktop-like (Silverlight) applications. Interaction between View and ViewModel now looks as simple as possible. Actually on the pattern schema there is no visible interaction arrow coming from View. It gives unit testing benefit - ViewModel can be tested fully independently and preserves minimal connection efforts.
Of course, the backlashes exist. One of them for instance says that MVVM costs considerable system resources and performance suffers due to declarative nature. Another says that the ViewModel does not directly describe the View and in large enterprise applications maintaining ViewModels adds difficulties. In spite of these arguments I must say that maximum performance and efficient usage of system resources are not major characteristics of UI. While code will grow it should be regularly managed. So problems with large applications I would refer to common problems. It’s the second question how MVVM can help or not.
In the last example you can see that the ViewModel is abstract (independent from the View), but however knows a lot about what the View is going to do. For instance, the ViewModel watches over deleted items from the cars collection outside itself and offers editable RGB color components. It would be better to take this code from the ViewModel to the View like the BrushConverter code. Doing this sometimes can be possible, but then can bring unprofitable, rather complicated solution. In this regard a ViewModel doesn’t form pure abstraction from its View. Perhaps it will be possible while XAML offers new instruments.

Linq-to-object and another syntax sugar



C# 3.0 has other features like linq-to-object, implicitly typed local variables, object and collection initializers, anonymous types, automatically implemented properties, etc. It is essential part of programming with C# 3.0, but it affects only syntax, not concepts. That’s why I didn’t bring it to front of this post. The only thing I must say that it really maintains the Microsoft slogan - .NET framework serves the purpose ‘What to code’ and not ‘How to code’. In practice code becomes more compact and after some programming experience easier to read and write. See the last example with Linq and other features.

Conclusion



In this post I’ve explained programming with C# 3.0 and WPF. My approach is using ViewModel pattern and most of C# 3.0 and XAML opportunities and not using event-driven style and callbacks. The style presents mix of imperative programming, where a sequence of commands is defined straight forward up to a ViewModel, and declarative syntax of C# 3.0, which improves reading and compact size.

Thursday, March 5, 2009

C# vs. C++. In chase of performance

Hey, folks. I continue my previous theme. Today I’m going to talk about c# managed and c++ native environments. What performance and memory issues can appear? What’s "managed" mean here? What’s the conclusion?

Repeatedly I saw software engines based on .NET virtual machine with C++ staffs. Of course, if an engine is intended for .NET auditory it’s the good way to expose exuberant .NET API. However, the question that worried me was when it is time to migrate to a virtual machine when much performance-critical logic must be written. How this logic is slowed down when it is under managed environment.
Immediately I must say that there is another critical-performance niche where C++/C might be combined with assembler instructions and where obviously C# doesn’t dwell. I’m not familiar with this domain and I don’t score it here.

Test


I chose operations over a hierarchy tree. The test is synthetic. However, all of its parts (side by side element’s creation, up/down iteration and removing) can successfully exist in real logic. For both environments I chose standard solutions: C++ STL containers and streams and C# generics and IO. Both read the same operation sequences from files and calculated the same checksums.

My first results confused me. Surprisingly, C++ solution sucked. After some exploration I had found that C++ file stream was slower than C# one, because it possessed safe extraction from any sequence with special symbols. In C# I relied on some predefined special symbols sequence. So I replaced text files with binary files with predefined semantic. Also I emptied C# garbage collector to get the full element's removing equivalent.

All measurements were done side by side and alternately. So an idle/busy state of an operating system must influence to both applications equally.

Results






Average spent time, secResident memory, MB
C# (.NET2.0)1,76130,6
C++(VC8.0)1,83826,2

This situation is the nonsense. In any case C++ loses C#. Next endevour is to use Visual Studio 2003.




Average spent time, secResident memory, MB
C# (.NET2.0)1,71830,6
C++(VC7.1)0,8925,4

It's more likely. Searching Internet I've found next useful links:
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/4431bab9-7c6e-4907-8e85-66ac8798dbc6/
http://www.jenkinssoftware.com/raknet/forum/index.php?topic=2091.0
As expected applying additional compiler options doesn't help:




Average spent time, sec
C# (.NET2.0)1,757
C++(VC8.0 + compiler options)1,785

So, try to guess, what's the real reason of this C++ slowing down?


What's in Linux.





Average spent time, secResident memory, MB
C# (mono + .NET2.0)2,9351,8 (mono)
C++ (wine + VC7.1)1,2526,8 + 7,9 (wine) = 34,7
C++(g++)1,4513,4

Another nonsense. Bravo, ms guys! Your solution beats native one. You can if you want.

Conclusion


When performance can be the argument when you choose between C# and C++? In the term of common performance I think it's not the argument, even for engines. Only in solutions where logic routines (looped, real-time virtual processors ...) must out maximum performance C++ is the key, because it’s more flexible (for instance, libraries faster than standard STL exist – you can build your own framework) and managed environment features (type checking ...) must be avoided by definition.
In any case one private kludge can bring more performance issues than a programming environment at all.

Saturday, February 21, 2009

C# vs. C++

Today I’m going to bring the programming monsters together, compare its environment features and calculate their bout points. It’s impossible to cover all in one post, so here I’m going to talk about something that make up development philosophy, peculiar attributes in contrast to each other.

C++ strengths


1) friend


Friend declaration allows one class to get access to non-public members of another class. On the first look this feature is redundant and means nothing but object-oriented principles violation. However, I can figure four reasons where it’s important to have friends.
  • Non-public constructors/destructors. This case covers different creational patterns.

  • Non-public methods which however are not intended for internal class usage. This technique allows usage of non-public class interface only by special class, group of classes or proxies.

  • Lack of direct access to class data for some operation that a class doesn’t respond itself. The best example here is (de)serialization. Moreover, you can see that C# XmlSerializer undermines data encapsulation process completely.

  • Highly coupled by design classes as an alternative to nested classes.

  • The alternative to c++ friend is c# internal keyword, which is the part of friend assembly technique. However, I can’t say that it’s equivalent.

    2) const


    In c++ there are two intrinsic const goals, which were omitted in c#.
  • Passing arguments with const keyword to methods prevents its further modification in the methods.

  • Marking class methods with const keyword creates an assurance that class data are read only in the methods.

  • Of course, these techniques require additional workload, but it’s very powerful feature. Often a const keyword says more than enclosed method documentation.

    3) Memory model


    My pretence to c# is the excessive memory simplification. It becomes a problem when you need to pass structure (value-type) by reference, and vice versa, to pass class (reference-type) by value. The first case was solved by adding ref/out keywords (except the situation with a method’s returning value by reference – it’s impossible because a value lifetime strictly depends on a method’s scope. But there is another example where we need to return this structure by reference – it’s also impossible). Excepting previous remark, things look normal here. A value by default is an optimal approach and when you really need a reference, ref/out keywords appear.
    More complicated situation we have with the second case. When you need to pass an object by value, you should clone it. ICloneable interface is intended for it. However, you can’t see any method’s declaration signs that an object is passed by value. It’s potential pitfall. Another interesting thing is that you can use ref/out keywords with reference types. It’s a rough equivalent to c++ reference to pointer. Next c# code snippet demonstrates it:

    public class A
    {
    }

    class Program
    {
    static void Method(A a)
    {
    a = new A();
    }
    static void Method(ref A a)
    {
    a = new A();
    }
    static void Main()
    {
    A a = null;
    Method(a);
    Console.WriteLine(a == null);//True
    Method(ref a);
    Console.WriteLine(a == null);//False
    }
    }

    In c++ the concepts of pointer and reference with the operators arrow, dot, dereference and address-of solve all possible tasks in the generalized manner without any ad hoc solutions.
    Another problem is the garbage collector. Yes, it frees you from memory managing, but however it also frees you from thinking about memory usage at all. new keyword in c++ is not a simple operator to create an object, it creates a heap object and the purpose of this creation is an obvious intention to keep up object’s lifetime.
    Of course I cannot but mention about famous c++ memory leaks. Well, they are not such horrible as people say. Dangling pointers that don’t leave your code are solved easy. Problems can be with third-party APIs and foreign code where a solution becomes harder. However, I can’t drop this c++ point due to this reason.

    4) header/source organization


    Another pretty c++ thing is headers. I don’t mean a compilation/linkage model (here c++ is much more difficult than c#), but mean header as contents of a module and header + source as a complete module. Abstraction and modularity are the key design concepts and c++ makes the cut, c# approach that uses only source files and one source file is class declaration & definition doesn’t fascinate me.

    5) cross-platform feature


    In case when a project or its part can be potentially cross-platform or uses Linux, Mac as a primary environment, or uses third-party cross-platform libraries already written in c++, c++ becomes a good choice to get native cross-platform code.

    C# strengths.


    1) interface


    Interface is the amazing thing that c# gives. I don’t mean the technical approach (by the way I think c++ with multiple inheritance is better here because it can include not only a behavior but private data also, which forms a completed reusable block), but mean the ideological approach – how framework classes reuses interfaces and how it increases abstraction on the whole. Learning an API becomes easier. Ideally, you learn a class description and interfaces that a class implements. The number of interfaces is much more less than classes in an API. The difference between inheritance and interface is that inheritance considerably helps to reuse code but unfortunately doesn’t help to create good abstraction. Interface, which is the evolved form of abstract class, makes a contract and each class that implements it must adhere to its contract. Moreover, interfaces go through class hierarchies.

    2) Environment benefits.


  • .NET Framework code style naming convention. To tell the truth I’ve been using it everywhere.

  • Visual Studio maybe the best development environment even for cross-platform based c++ projects. But some features like code auto-formatting (ctrl-K-D), Refactor menu and so on belong to c# only.

  • Faster, easier and more careful compilation.


  • 3) ASP + ADO


    This collaboration forms the complete platform for web portals or any web server based solutions. It’s the stock phrase, which embodies web/data programming based on MS Windows platform + MS SQL Server.

    4) WPF


    GUI programming evolves very well. Since .NET 3.0 it aims to any desktop/web environment in generalized manner including animation, 2D/3D graphics, multimedia features.

    5) WCF


    Service-oriented features also evolve. Since .NET 3.0 Web Services and Remoting are generalized into one package.

    Conclusion.


    So for today what’s the reason to choose between C# and C++? If we talk about IT-related projects c# becomes the obvious choice. If we talk about programming projects we should look into C++ points 5 and also 3 and C# points from 3 through 5. Depending on project’s complexity both can be the choice. However the most important matter here is performance and machine resources cost. Actually I haven’t mentioned about c# managed environment vs. c++ native. It’s another discussion and it must be uncovered later.
    Another programming niche is maintaining existing projects and here c++ is on demand. Migrating stuff doesn’t help.

    Saturday, January 31, 2009

    extern pitfalls in G++

    Look at the example:
    unit1.cpp

    #include <iostream>
    using namespace std;

    int I = 2;
    extern const int J = 10;
    void FuncI();
    void FuncJ();


    int main()
    {
    cout << hex;
    cout << "I, before " << I << " " << *(&I + 1) << endl;
    FuncI();
    cout << "I, after " << I << " " << *(&I + 1) << endl;
    FuncJ();
    }


    unit2.cpp

    extern long long I;
    extern int J;


    void FuncI()
    {
    I = I << 36;//causes contiguous memory damage
    }


    void FuncJ()
    {
    J++;//causes segmentation fault
    }


    The program compiles fine and the results are:

    I, before 2 0
    I, after 0 20
    Segmentation fault


    Why g++ compiler is so spoiled here. I don't know. In Visual Studio it's impossible to do such nasty things.

    Sunday, January 25, 2009

    Singleton pattern C++. My recipe.

    Look into example

    #include <iostream>
    #include "SingletonPattern.h"


    class A : public ISingleton<A>
    {
    //a few extra movements (friend declarations) is needed to create own non-public default ctor and dtor.
    A() { j = 10;};
    ~A() {std::cout << "~A" << std::endl;};
    friend class ISingleton<A>;
    friend class std::auto_ptr<A>;

    public:
    //do not define any public ctors and dtor.
    //do not define copy ctor and assign operator at all.

    static int j;
    void Test(int i) { std::cout << "A::Test(" << i << ") " << ++j << std::endl;};
    };
    int A::j = 10;


    class B : public ISingleton<B>
    {
    public:
    void Test(int i) { static int j = 0; std::cout << "B::Test(" << i << ") " << ++j << std::endl;};
    };


    class C : public ISingleton<C>
    {
    public:
    virtual void Test(int i) { static int j = 0; std::cout << "C::Test(" << i << ") " << ++j << std::endl;};
    };


    class D : public C
    {
    public:
    void Test(int i) { static int j = 0; std::cout << "D::Test(" << i << ") " << ++j << std::endl;};
    };


    int main()
    {
    A::GetSingleton().Test(5);
    A& a = A::GetSingleton();
    a.Test(6);
    // A anotherA = A::GetSingleton();//compilation error, ok
    // a = a;//compilation error, ok

    B::GetSingleton().Test(3);
    B& b = B::GetSingleton();
    b.Test(100);
    C::GetSingleton().Test(33);
    D::GetSingleton().Test(23);//it doesn't work for D because ISingleton was defined for parent class C
    b.Test(15);
    }


    A::Test(5) 11
    A::Test(6) 12
    B::Test(3) 1
    B::Test(100) 2
    C::Test(33) 1
    C::Test(23) 2
    B::Test(15) 3
    ~A



    There are 3 singleton classes (A, B, C). As you see it's very simple to create singleton class, only inherit public ISingleton<ThisClass>.
    A few cautions however are written on lines 7, 14, 15. First belongs to own default ctor and dtor. Well, usually singleton class encapsulates heap objects, so own destructor is needed. Own default constructor maybe also useful, but if initialization with arguments is needed, custom Init method is the case because ctors with arguments are unavailable with this singleton implementation.

    Ok, look at the implementation code.

    #ifndef _SINGLETON_PATTERN_INTERFACES_SVOLKOV_
    #define _SINGLETON_PATTERN_INTERFACES_SVOLKOV_


    #include <memory>


    template <class T>
    class ISingleton
    {
    protected:
    ISingleton();
    ~ISingleton();
    private:
    ISingleton(const ISingleton&);
    ISingleton& operator= (const ISingleton&);
    static std::auto_ptr<T> _ptr;
    friend class std::auto_ptr<T>;
    public:
    ///Get singleton instance.
    static T& GetSingleton();
    };


    template <class T>
    std::auto_ptr<T> ISingleton<T>::_ptr;


    template <class T>
    ISingleton<T>::ISingleton()
    {
    }


    template <class T>
    ISingleton<T>::~ISingleton()
    {
    }


    template <class T>
    T& ISingleton<T>::GetSingleton()
    {
    if (!_ptr.get())
    _ptr = std::auto_ptr<T>(new T());
    return *(_ptr.get());
    }


    #endif

    Lazy initialization is used to postpone instantiation process. Standard smart pointer is used to destroy object automatically when program is closing. This instantiation/deletion model is exactly what is usually needed for a singleton manager etc.
    Please note that it's single-threaded pattern implementation, not multi-threaded.

    Saturday, January 24, 2009

    SIGSEGV on statement with std::string variable, G++.

    If you have error report like

    Program received signal SIGSEGV, Segmentation fault.
    0xb7d2be69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
    (gdb) where
    #0 0xb7d2be69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
    #1 0xb7d0dfcc in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string () from /usr/lib/libstdc++.so.6
    ...

    or

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0xb746b6d0 (LWP 9469)]
    0xb7c5ce69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
    (gdb) where
    #0 0xb7c5ce69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
    #1 0xb7c3e8e4 in std::string::assign () from /usr/lib/libstdc++.so.6
    #2 0xb7c3e944 in std::string::operator= () from /usr/lib/libstdc++.so.6
    ...

    or something similar,
    check that memory under string variable isn't corrupted.
    In my case the problem was with zeroed memory. In Visual Studio I used the ugly but effective construction like

    string a;
    memset(&a, 0, sizeof(a));

    and I didn't have problems with it. But in g++ and in general I must be more accurate.