0

I've seemed to bump my head into the following

I understand that reflection can be costly when run at an at lib basis, with no caution thrown into the wind. How costly is .NET reflection?

But say I've got the following, and I intend to use it on my web API endpoints. like so:

  public AnotherDto Get(int someId)
  {
      var item = this.repo.FindAll(o => o.Id == someId)
                          .Take(1).Map<SomeDto>()
                          .FirstOrDefault();   

      var result = this.otherRepo
                       .FindAll(o => o.Id == item.Id)
                       .Map<AnotherDto>();    

      return result;
  }

Where Map<>()

public static IEnumerable<U> Map<U>(this IEnumerable<object> e)
    {
        var method = typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)     
        .Where(m => m.Name == "Map" && m.GetGenericArguments().Length == 2)
        .Single();
        method = method.MakeGenericMethod(e.GetType().GetGenericArguments()[0], typeof(U));

        return method.Invoke(null, new object[] { e}) as IEnumerable<U>;
    }

Is this something that would be seen as code that would knock back performance to such an extent as to warrant not using it?

Community
  • 1
  • 1
Rohan Büchner
  • 5,333
  • 4
  • 62
  • 106
  • 5
    Why don't you [measure it](http://msdn.microsoft.com/cs-cz/library/system.diagnostics.stopwatch(v=vs.110).aspx)? – twoflower Mar 03 '14 at 12:45
  • 3
    This all depends on how often it's called. For that sort of thing I generally lean towards something like [AutoMapper](https://github.com/AutoMapper/AutoMapper) or [ValueInjecter](http://valueinjecter.codeplex.com/) or if you are really after speed [EmitMapper](http://emitmapper.codeplex.com/). – James Mar 03 '14 at 12:46
  • Good suggestion. I'll definitely try it out. Would this be considered a valid way to benchmark this? – Rohan Büchner Mar 03 '14 at 12:49
  • @RohanBüchner `Stopwatch` class is fine for benchmarking, however, make sure you benchmark using realistic data, ideally you would want to use it in some real scenarios. – James Mar 03 '14 at 12:50
  • I am using AutoMapper inside the Map extension. It basically creates the map on the fly as opposed to specifying a map upfront. I wanted to modify our current instance to infer the source type, as opposed to go ".SomeMapper(a)" – Rohan Büchner Mar 03 '14 at 12:58
  • @James, our solution is very new, and thus we have little to no data. I'll construct a test client to replicate this. I was hoping there might be some industry standard/recommendation in regards to this – Rohan Büchner Mar 03 '14 at 13:00
  • @RohanBüchner standard/recommendation to what? Benchmarking? – James Mar 03 '14 at 13:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/48876/discussion-between-rohan-buchner-and-james) – Rohan Büchner Mar 03 '14 at 13:20
  • This might be better suited to codereview.stackexchange.com – Jim Jeffries Mar 03 '14 at 14:39

2 Answers2

1

Firstly, chances are that this will not be the part of your application that is your bottleneck. For example, your use of the repository pattern suggests that you are talking to a database. This will be significantly slower than the code posted here. Profile your application and see what is slow and therefore worth spending time optimising.

Seocndly, to address your code, the only potential issue you should be aware of is that as you are returning an IEnumerable it could be evaluated multiple times which would cause the code to be run multiple times. To mitigate the added complexity this adds you should cache the result so that it will only get called once.

Jim Jeffries
  • 9,841
  • 15
  • 62
  • 103
0

Cache the method and then in the Map just invoke it. Then the reflection performance hit will be only once.

stepandohnal
  • 457
  • 4
  • 13