Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Does the use of many trivial classes with generics pose a performance penalty?

Does the use of many trivial classes with generics pose a performance penalty?

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharpdesignperformancetutorialquestion
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    supercat9
    wrote on last edited by
    #1

    Using generics and interfaces in .net, it's possible to design a class so that a particular method name can invoke a number of different methods, based upon the type of a passed-in parameter. For example:

    Class DoItMagic
    Interface iAct(Of T)
    Sub Act(ByVal param As T)
    End Interface

    Public Shared Sub exec(Of T)(ByVal target As iAct(Of T), ByVal param As T)
        target.Act(param)
    End Sub
    
    Public Shared Sub hitEverything(Of T, U As DoItMagic.iAct(Of T))(ByVal theEnum As IEnumerable(Of U), ByVal theParam As T)
        For Each thing As U In theEnum
            exec(Of T)(thing, theParam)
        Next
    End Sub
    

    End Class

    Class DoItTarget
    Implements DoItMagic.iAct(Of param1), DoItMagic.iAct(Of param2)

    Class param1
    End Class
    
    Class param2
    End Class
    
    Public Sub Act\_param1(ByVal param As param1) Implements DoItMagic.iAct(Of param1).Act
    
    End Sub
    
    Public Sub Act\_param2(ByVal param As param2) Implements DoItMagic.iAct(Of param2).Act
    
    End Sub
    

    End Class

    Class DoItTest
    Dim firstParam As DoItTarget.param1
    Dim secondParam As DoItTarget.param2

    Dim L As List(Of DoItTarget)
    
    Sub go()
        DoItMagic.hitEverything(Of DoItTarget.param1, DoItTarget)(L, firstParam)
        DoItMagic.hitEverything(Of DoItTarget.param2, DoItTarget)(L, secondParam)
    End Sub
    

    End Class

    This approach seems to work out pretty elegantly. The first hitEverything will call iAct(of Param1) on each element of the list; the second will call iAct(of Param2). Additional methods may be added by simply creating new classes and adding interface iAct(of eachNewClass), without any need to change anything in DoItMagic. My questions:

    1. Are there any performance implementations with creating empty classes that are used as method selectors rather than as distinct ways of holding data (e.g. there might be a number of different classes that hold a single integer, but select different methods).
    2. Does invoking methods via generics pose any performance problems in cases where everything can be type-checked at compile time?
    3. What would be the performance implications in cases where things couldn't be checked until run-time (e.g. if a list holds a number of elements, not all of which will support any particular iAct(of type).
    4. Is this overall approach a brilliant idea, crazy idea, or somewhere in between?

    I like the way this approach seems to work, but I would be very sad if I develo

    U M 2 Replies Last reply
    0
    • S supercat9

      Using generics and interfaces in .net, it's possible to design a class so that a particular method name can invoke a number of different methods, based upon the type of a passed-in parameter. For example:

      Class DoItMagic
      Interface iAct(Of T)
      Sub Act(ByVal param As T)
      End Interface

      Public Shared Sub exec(Of T)(ByVal target As iAct(Of T), ByVal param As T)
          target.Act(param)
      End Sub
      
      Public Shared Sub hitEverything(Of T, U As DoItMagic.iAct(Of T))(ByVal theEnum As IEnumerable(Of U), ByVal theParam As T)
          For Each thing As U In theEnum
              exec(Of T)(thing, theParam)
          Next
      End Sub
      

      End Class

      Class DoItTarget
      Implements DoItMagic.iAct(Of param1), DoItMagic.iAct(Of param2)

      Class param1
      End Class
      
      Class param2
      End Class
      
      Public Sub Act\_param1(ByVal param As param1) Implements DoItMagic.iAct(Of param1).Act
      
      End Sub
      
      Public Sub Act\_param2(ByVal param As param2) Implements DoItMagic.iAct(Of param2).Act
      
      End Sub
      

      End Class

      Class DoItTest
      Dim firstParam As DoItTarget.param1
      Dim secondParam As DoItTarget.param2

      Dim L As List(Of DoItTarget)
      
      Sub go()
          DoItMagic.hitEverything(Of DoItTarget.param1, DoItTarget)(L, firstParam)
          DoItMagic.hitEverything(Of DoItTarget.param2, DoItTarget)(L, secondParam)
      End Sub
      

      End Class

      This approach seems to work out pretty elegantly. The first hitEverything will call iAct(of Param1) on each element of the list; the second will call iAct(of Param2). Additional methods may be added by simply creating new classes and adding interface iAct(of eachNewClass), without any need to change anything in DoItMagic. My questions:

      1. Are there any performance implementations with creating empty classes that are used as method selectors rather than as distinct ways of holding data (e.g. there might be a number of different classes that hold a single integer, but select different methods).
      2. Does invoking methods via generics pose any performance problems in cases where everything can be type-checked at compile time?
      3. What would be the performance implications in cases where things couldn't be checked until run-time (e.g. if a list holds a number of elements, not all of which will support any particular iAct(of type).
      4. Is this overall approach a brilliant idea, crazy idea, or somewhere in between?

      I like the way this approach seems to work, but I would be very sad if I develo

      U Offline
      U Offline
      User 3623376
      wrote on last edited by
      #2

      Here is my experience. You will have overall performance boost by using OOPS and Generics. I have a project where I have used many classes and many generics almost in the same way as you are doing it. We did a performance test by bombarding with several request to the project and it performed better as against using OOPS without generics (many many classes and hence objects). Generics gives the ability to precast and late binding, and also once loaded in memory it stays there to be consumed upon request.

      1 Reply Last reply
      0
      • S supercat9

        Using generics and interfaces in .net, it's possible to design a class so that a particular method name can invoke a number of different methods, based upon the type of a passed-in parameter. For example:

        Class DoItMagic
        Interface iAct(Of T)
        Sub Act(ByVal param As T)
        End Interface

        Public Shared Sub exec(Of T)(ByVal target As iAct(Of T), ByVal param As T)
            target.Act(param)
        End Sub
        
        Public Shared Sub hitEverything(Of T, U As DoItMagic.iAct(Of T))(ByVal theEnum As IEnumerable(Of U), ByVal theParam As T)
            For Each thing As U In theEnum
                exec(Of T)(thing, theParam)
            Next
        End Sub
        

        End Class

        Class DoItTarget
        Implements DoItMagic.iAct(Of param1), DoItMagic.iAct(Of param2)

        Class param1
        End Class
        
        Class param2
        End Class
        
        Public Sub Act\_param1(ByVal param As param1) Implements DoItMagic.iAct(Of param1).Act
        
        End Sub
        
        Public Sub Act\_param2(ByVal param As param2) Implements DoItMagic.iAct(Of param2).Act
        
        End Sub
        

        End Class

        Class DoItTest
        Dim firstParam As DoItTarget.param1
        Dim secondParam As DoItTarget.param2

        Dim L As List(Of DoItTarget)
        
        Sub go()
            DoItMagic.hitEverything(Of DoItTarget.param1, DoItTarget)(L, firstParam)
            DoItMagic.hitEverything(Of DoItTarget.param2, DoItTarget)(L, secondParam)
        End Sub
        

        End Class

        This approach seems to work out pretty elegantly. The first hitEverything will call iAct(of Param1) on each element of the list; the second will call iAct(of Param2). Additional methods may be added by simply creating new classes and adding interface iAct(of eachNewClass), without any need to change anything in DoItMagic. My questions:

        1. Are there any performance implementations with creating empty classes that are used as method selectors rather than as distinct ways of holding data (e.g. there might be a number of different classes that hold a single integer, but select different methods).
        2. Does invoking methods via generics pose any performance problems in cases where everything can be type-checked at compile time?
        3. What would be the performance implications in cases where things couldn't be checked until run-time (e.g. if a list holds a number of elements, not all of which will support any particular iAct(of type).
        4. Is this overall approach a brilliant idea, crazy idea, or somewhere in between?

        I like the way this approach seems to work, but I would be very sad if I develo

        M Offline
        M Offline
        Mark Churchill
        wrote on last edited by
        #3

        Why not just use the build in List< U>.ForEach(instance.Act)? If you need to use IEnumerable, then a trivial extension method would work: static void ActOnABunchOfStuff< U>(IEnumerable< U> bunch, Action< U> action) { foreach(var stuff in bunch) action(stuff); } Use with: int[] foo = {1,2,3,4,5}; ActOnABunchOfStuff(foo, doItTarget.Act); VB-i-cise it at your leisure ;)

        Mark Churchill Director, Dunn & Churchill Pty Ltd Free Download: Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.
        Entanglar: .Net game engine featuring automatic networking and powerful HLSL gfx binding.

        S 1 Reply Last reply
        0
        • M Mark Churchill

          Why not just use the build in List< U>.ForEach(instance.Act)? If you need to use IEnumerable, then a trivial extension method would work: static void ActOnABunchOfStuff< U>(IEnumerable< U> bunch, Action< U> action) { foreach(var stuff in bunch) action(stuff); } Use with: int[] foo = {1,2,3,4,5}; ActOnABunchOfStuff(foo, doItTarget.Act); VB-i-cise it at your leisure ;)

          Mark Churchill Director, Dunn & Churchill Pty Ltd Free Download: Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.
          Entanglar: .Net game engine featuring automatic networking and powerful HLSL gfx binding.

          S Offline
          S Offline
          supercat9
          wrote on last edited by
          #4

          Why not just use the build in List< U>.ForEach(instance.Act)? Are you assuming Action< U> is a delegate for a void function that takes a single parameter of type U? I'm not terribly familiar with C# syntax, and I don't see any declaration for Action. Also, I would guess that the last statement was supposed to be ActOnABunchOfStuff< integer>(foo, doItTarget.Act); but the board gobbled up what it thought was a tag? If all the items in the list are of the same concrete type, I suppose that approach would work, at the expense of generating lots of silly little wrapper functions. Maybe that's no worse than generating silly little classes, but the generics approach I describe could offer another benefit that might be harder to achieve without generics: one could have a list of objects and do an enumerated invoke with something like if typeof(it) is iAct(of T) Then CType(it, iAct(of T)).Act(whatever). Not sure what the performance of that would be, but it would allow one to achieve a form of event handling without requiring every item to create a delegate for every different event that it supports. One could do such 'typeof/is' testing in a wrapper function, but that would seem a bit inelegant.

          M 1 Reply Last reply
          0
          • S supercat9

            Why not just use the build in List< U>.ForEach(instance.Act)? Are you assuming Action< U> is a delegate for a void function that takes a single parameter of type U? I'm not terribly familiar with C# syntax, and I don't see any declaration for Action. Also, I would guess that the last statement was supposed to be ActOnABunchOfStuff< integer>(foo, doItTarget.Act); but the board gobbled up what it thought was a tag? If all the items in the list are of the same concrete type, I suppose that approach would work, at the expense of generating lots of silly little wrapper functions. Maybe that's no worse than generating silly little classes, but the generics approach I describe could offer another benefit that might be harder to achieve without generics: one could have a list of objects and do an enumerated invoke with something like if typeof(it) is iAct(of T) Then CType(it, iAct(of T)).Act(whatever). Not sure what the performance of that would be, but it would allow one to achieve a form of event handling without requiring every item to create a delegate for every different event that it supports. One could do such 'typeof/is' testing in a wrapper function, but that would seem a bit inelegant.

            M Offline
            M Offline
            Mark Churchill
            wrote on last edited by
            #5

            With that last statement, the type parameter U is inferred (at least in C#) from the type of foo (which is as you say an int). System.Action(Of T) is in mscorlib, and has the signature you guessed. Theres also a couple of others with extra parameters. I may have got a little confused with what you are trying to achieve. Invoking a method on each instance in a list, passing the same parameters? I would use the equivalent of listOfThings.ForEach(x => x.SomeMethod(p1,p2,p3,etc));. This might be a little messy in VB though.

            Mark Churchill Director, Dunn & Churchill Pty Ltd Free Download: Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.
            Entanglar: .Net game engine featuring automatic networking and powerful HLSL gfx binding.

            S 1 Reply Last reply
            0
            • M Mark Churchill

              With that last statement, the type parameter U is inferred (at least in C#) from the type of foo (which is as you say an int). System.Action(Of T) is in mscorlib, and has the signature you guessed. Theres also a couple of others with extra parameters. I may have got a little confused with what you are trying to achieve. Invoking a method on each instance in a list, passing the same parameters? I would use the equivalent of listOfThings.ForEach(x => x.SomeMethod(p1,p2,p3,etc));. This might be a little messy in VB though.

              Mark Churchill Director, Dunn & Churchill Pty Ltd Free Download: Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.
              Entanglar: .Net game engine featuring automatic networking and powerful HLSL gfx binding.

              S Offline
              S Offline
              supercat9
              wrote on last edited by
              #6

              The basic concept is that I have an class for objects that contain a number of objects that the class doesn't really understand in detail (an iEnumerable is a common example of such a thing, though hardly the most sophisticated) and I would like for code outside the class to be able to invoke methods on some or all of the objects within, generally passing the same parameters to all. In some regards similar to delegates, except (1) delegates are hard-wired for particular method-object pairs, and (2) there is no need to hold the method info for a delegate without holding a hard reference to the object. One class I created using this approach (which seems to work nicely, though I haven't benchmarked its behavior in a program with hundreds of classes) manages something like event subscription, but using weak references. Any number of objects may subscribe to a 'publisher' object; performing .Exec(of T) on the publisher object will cause it to call function iAct(of T).Act on any subscribed object supporting interface iAct(of T). Subscription and unsubscription are O(1), non-locking, and thread-safe; an object will be unsubscribed if it (1) gets garbage-collected, (2) uses the Unsubscribe method of the Subscription object returned when the object originally subscribed, or (3) one of its iAct(of T) functions returns True when invoked. My original intended application for this class would be in an application where a number of forms have controls that affect the same properties and should thus all affect each other. While events provide a nice way to achieve much of that functionality, all the forms need a reference to an object that will support all of the events they need. If new events are added, the linking object will have to be extended to support them. Worse, using events creates the possibility of memory or resource leaks if any objects don't get properly disposed. Finalizers won't do any good if delegates keep objects alive forever. Using my actionLink class avoids these difficulties; if I create a class called e.g. volumeChangedParam, I can call Exec(of volumeChangedParam) on my event publisher object and any subscribed object that supports an iAct(of volumeChangedParam) will have its iAct(of volumeChangedParam).Act function called. The actionLink class doesn't have to know anything about volumeChangedParam or any of the other classes it works with; additional classes could be added to support other operations. All this stuff seems to work fine, but I wouldn't want to engineer too much of a sy

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups