by Keyvan Nayyeri via Keyvan Nayyeri on 6/2/2007 5:26:09 PM
[Update: Jason Stangroome has a valuable comment on my post to improve its performance.]
While unit testing BlogML project, I faced with some classes that hadn't overridden Object.Equals() method to let me run my tests so I had to override this method for them. For some classes with a few properties this was easy but suddenly I saw a few classes with more than 3-4 properties and class itself was a collection. Thus, I had to iterate through its items and check them one be one to make sure all properties for all objects at same indexes are equal.
Implementing such a code wasn't so hard for my classes with less than 5-6 properties but in general I'm lazy when it comes to writing this kind of code. So I thought about investigating an alternative solution for a long casing statement and finally ended up with using reflection to iterate through all properties of a type and compare its value for both objects at same index. Here something appeared in my mind about performance effect of this solution and stopped me from implementing my code quickly. So I got off and built a small project to calculate the approximate performance of both solutions. The result was as I expected and you'll see it in this post.
If you're interested to see what I did to compare the performance of both methods and its results, follow this post otherwise it doesn't have anything for you but before leaving it I'd like to have a notice for you: when using reflection in your code, take care about performance because it can have a huge effect on your code. Choosing between reflection based solutions and other solutions needs some experience with reflection. There are some cases where it's better to use reflection. You can read them on some articles.
But about my small performance checker application! First I had to simulate my real situation in this small project. So I created an Author class with five fields.
using System;
using System.Xml.Serialization;
[Serializable()]
public class Author
{
private string id;
private string title;
private DateTime dateCreated = DateTime.Now;
private bool approved = true;
private string email;
[XmlAttribute("id")]
public string ID
get { return this.id; }
set { this.id = value; }
}
[XmlElement("title")]
public string Title
get { return this.title; }
set { this.title = value; }
[XmlAttribute("date-created", DataType = "dateTime")]
public DateTime DateCreated
get { return this.dateCreated; }
set { this.dateCreated = value; }
[XmlAttribute("approved")]
public bool Approved
get { return this.approved; }
set { this.approved = value; }
[XmlAttribute("email")]
public string Email
get { return this.email; }
set { this.email = value; }
The next step was to create an AuthorCollection1 class which overrides Object.Equals() method with reflection.
using System.Collections.Generic;
using System.Reflection;
[Serializable]
public sealed class AuthorCollection1 : List<Author>
public override bool Equals(object obj)
AuthorCollection1 authors = obj as AuthorCollection1;
foreach (Author author in authors)
int i = 0;
Author original = this[i];
foreach (PropertyInfo property in Type.GetType(typeof(Author).ToString()).GetProperties())
if (property.GetValue(author, null) != property.GetValue(original, null))
return false;
i++;
return true;
public override int GetHashCode()
return base.GetHashCode();
On the other side, AuthorCollection2 overrides this method with if statement.
public sealed class AuthorCollection2 : List<Author>
AuthorCollection2 authors = obj as AuthorCollection2;
if ((author.ID != original.ID) ||
(author.Title != original.Title) ||
(author.Email != original.Email) ||
(author.DateCreated != original.DateCreated) ||
(author.Approved != original.Approved))
And finally a code to create instances of these classes and give them some sample values. authors1 and authors2 are instances of AuthorCollection1 to call Equals() method for this class and authors3 and authors4 are instances of AuthorCollection2 to call its Equals() method.
protected void Page_Load(object sender, EventArgs e)
AuthorCollection1 authors1 = new AuthorCollection1();
AuthorCollection1 authors2 = new AuthorCollection1();
AuthorCollection2 authors3 = new AuthorCollection2();
AuthorCollection2 authors4 = new AuthorCollection2();
Author author1 = new Author();
author1.ID = "2101";
author1.Title = "Keyvan Nayyeri";
author1.Email = "someone1@somewhere.com";
author1.DateCreated = DateTime.Now;
author1.Approved = true;
authors1.Add(author1);
authors2.Add(author1);
authors3.Add(author1);
authors4.Add(author1);
Author author2 = new Author();
author2.ID = "2102";
author2.Title = "Darren Neimke";
author2.Email = "someone2@somewhere.com";
author2.DateCreated = DateTime.Now;
author2.Approved = false;
authors1.Add(author2);
authors2.Add(author2);
authors3.Add(author2);
authors4.Add(author2);
bool compare1vs2 = authors1.Equals(authors2 as object);
bool compare3vs4 = authors3.Equals(authors4 as object);
After running a performance test on this code, I got good results. As I had expected the cost of reflection based solution was more than the normal one. In all charts number 1 specifies statistics for AuthorCollection1.Equals() method and number 2 specifies statistics for AuthorCollection2.Equals() method.
Therefore in the next check-in, I have to replace my reflection code with traditional code. Of course, this was predicable. In BlogML, performance is a very very important parameter for us because often we deal with lots of blog data even though my Equals() overridden methods won't be called during imports or exports.
Any input from my readers on this topic would be great!
Original Post: Cost of Reflection
The content of the postings is owned by the respective author. CSharpFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on CSharpFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.