tags:

views:

533

answers:

8

Hi,

I'm trying to complete a practice question from a book on generics but the question doesn't make sense to me. Here it goes.

Create two classes with identical functionality. Use generics for the first class, and cast the second class to Object types. Create a for loop that uses class and the Object based class to determine which performs better.

I'm not sure what it means by casting to Object types. Here is my code so far

   //Generic
    class Person<T> {

        T var1;

        public Person(T yer) {
            var1 = yer;
        }

        public T Value { get { return var1; } }
    }

    //Normal class
    class Human {

        int var1;

        public Human(int yer) {
            var1 = yer;
        }

        public int Value { get { return var1; } }
    }

My main program running the loops

for (int i = 0; i < 1000000; i++) {
                Person<int> me = new Person<int>(1);
                int hey = me.Value;
            }

            for (int i = 0; i < 1000000; i++) {
                Human per = new Human(1);
                object her = (object)per.Value;
            }

I don't know if Im doing this right. Help please :-)

+6  A: 

I think that the question is asking you to create a collection class, and insert instances of your class into that.

E.g.,

Generics version:

List<Human> myList = new List<Human>();
Human h = new Human();
myList.Add(h);

Object version:

ArrayList myObjectList = new ArrayList();
Human h = new Human();
myObjectList.Add((object)h));

I haven't checked whether that compiles, and have to run now.

endian
Looping is missing here. Otherwise this looks good. Generic version will perform better. You can check this with the use of StopWatch class in System.Diagnostics.
Pradeep
Actually, since Human is a reference type,there is no boxing going on, so the timings will be nearly identical.
James Curran
A: 

I think you've got it right except for the for loops. An int is an object type so replace

object her = (object)per.Value;

with

int her = per.Value;

The other thing you're missing is some performance counters. Have a look at the Timer class to see what kinds of things you can do to see which is a better performer.

Chris Conway
"An int is an object type" That should be "An int is an VALUE type"
James Curran
A: 

I'm not sure, but it sounds to me like a question that is trying to test out your knowledge of boxing and unboxing rules.

int i = 123; object o = (object)i; // boxing

The object o can then be unboxed and assigned to integer variable i:

o = 123; i = (int)o; // unboxing

If an object gets boxed and unboxed it is slower as a new object gets created.

tdyen
A: 

Yes, you are doing it right. There isn't much you can do with pure Object instances as most operators don't work on them. There are four public methods defined: Equals, GetHashCode, GetType and ToString. I guess you could fiddle with Equals and see if that makes any difference.

DrJokepu
+1  A: 

I think the question is for looping over a collection of your classes.

Generic

List<Person> pList = new List<Person>();
for(int i = 0; i<1000; ++i)
    pList.Add(new Person(30));

StopWatch sw = new StopWatch();
sw.start();
int sum = 0;
foreach(Person p in pList)
    sum += p.Value;
sw.Stop();

Object

ArrayList hList = new ArrayList;
for(int i = 0; i<1000; ++i)
    hList.Add(new Human(30));

StopWatch sw = new StopWatch();
sw.start();
int sum = 0;
foreach(Object h in hList)
    sum += ((Human)h).Value;
sw.Stop();
Mats Fredriksson
Actually, since Human is a reference type,there is no boxing going on, so the timings will be nearly identical.
James Curran
A: 

Well if I am doing it right, then according to my counters (DateTime.Now.Ticks) then I can't see any difference in performance at all.

If I take endian's approach then I can see where the performance hit is.

Lets hope my exam questions are a little clearer.

Thanks everyone.

Sir Psycho
Agreed, the question doesn't seem very clear. Can you type it in exactly for us?
endian
If you are on dotnet framework 2.0 or above, you might want to take a look at System.Diagnostics.Stopwatch to do your timing. [http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx]
kinjal
kinjal: Generics were introduced in the .NET Framework 2.0
DrJokepu
+1  A: 

What you are being asked to do is use the Object inside your class, so Person<> is perfect. What you need to do is change Human so that Var1 is an object. Then, wherever you use var1 cast it to or from an int:

class Human 
{        
     object var1;
     public Human(int yer) 
     {            
          var1 = (object) yer;        
     }
     public int Value 
     { 
         get { return (int) var1;     }
     }    
}

The confusion come from the fact in this example, var1 really can't be anything besides an int, so it's really not a good candidate for generics, and in production should be written as you originally wrote Human. But as I wrote it, it's OK for this exercise.

James Curran
A: 

Hi All,

I'm new to this forum. I'm doing the same practice exercise mentioned in this question. the code behaves differently based on which object is created first.

Can you please look at the code below and point out what's wrong with it. thanks in advance.

class Generics_sample<T>
{
    public Generics_sample()
    {
        Console.WriteLine("Generics_sample class");
    }
    public long getTicks()
    {
        return DateTime.Now.Ticks;
    }
    public void display(T a)
    {
        Console.Write("{0}",a);
    }
}
class Object_sample
{
    public Object_sample()
    {
        Console.WriteLine("Object_sample class");
    }
    public long getTicks()
    {
        return DateTime.Now.Ticks;
    }
    public void display(Object a)
    {
        Console.Write("{0}", a);
    }
}

class Sample
{
    public static void Main(string[] args)
    {
        long ticks_initial, ticks_final, diff_generics, diff_object;
        Generics_sample<int> GS = new Generics_sample<int>();
        Object_sample OSample = new Object_sample();


        // Generics Sample 
        ticks_initial = 0; ticks_final = 0;
        ticks_initial = GS.getTicks();
        for (int i = 0; i < 50000; i++)
        {
            GS.display(i);
        }
        ticks_final = GS.getTicks();
        diff_generics = ticks_final - ticks_initial; 

        //Object Sample  ---- if instance of Object_sample is created first it shows lesser no.of difference in ticks
        ticks_initial = 0; ticks_final = 0;
        ticks_initial = OSample.getTicks();
        for (int j = 0; j < 50000; j++)
        {
            OSample.display(j);
        }
        ticks_final = OSample.getTicks();
        diff_object = ticks_final - ticks_initial;


        Console.WriteLine("\nPerformance of Generics {0}", diff_generics);
        Console.WriteLine("Performance of Object {0}", diff_object);
    }

}

Lakshmi