Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 216007
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T18:31:27+00:00 2026-05-11T18:31:27+00:00

I was doing some performance metrics and I ran into something that seems quite

  • 0

I was doing some performance metrics and I ran into something that seems quite odd to me. I time the following two functions:

  private static void DoOne()
      {
         List<int> A = new List<int>();
         for (int i = 0; i < 200; i++) A.Add(i);
          int s=0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < A.Count; c++) s += A[c];
         }

      }

   private static void DoTwo()
      {
         List<int> A = new List<int>();
         for (int i = 0; i < 200; i++) A.Add(i);
         IList<int> L = A;
         int s = 0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < L.Count; c++) s += L[c];
         }

      }

Even when compiling in release mode, the timings results were consistently showing that DoTwo takes ~100 longer then DoOne:

 DoOne took 0.06171706 seconds.
 DoTwo took 8.841709 seconds.

Given the fact the List directly implements IList I was very surprised by the results. Can anyone clarify this behavior?

The gory details

Responding to questions, here is the full code and an image of the project build preferences:

Dead Image Link

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Collections;

namespace TimingTests
{
   class Program
   {
      static void Main(string[] args)
      {
         Stopwatch SW = new Stopwatch();
         SW.Start();
         DoOne();
         SW.Stop();

         Console.WriteLine(" DoOne took {0} seconds.", ((float)SW.ElapsedTicks) / Stopwatch.Frequency);
         SW.Reset();
         SW.Start();
         DoTwo();
         SW.Stop();

         Console.WriteLine(" DoTwo took {0} seconds.", ((float)SW.ElapsedTicks) / Stopwatch.Frequency);

      }

      private static void DoOne()
      {
         List<int> A = new List<int>();
         for (int i = 0; i < 200; i++) A.Add(i);
         int s=0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < A.Count; c++) s += A[c];
         }

      }
      private static void DoTwo()
      {
         List<int> A = new List<int>();
         for (int i = 0; i < 200; i++) A.Add(i);
         IList<int> L = A;
         int s = 0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < L.Count; c++) s += L[c];
         }

      }
   }
}

Thanks for all the good answers (especially @kentaromiura). I would have closed the question, though I feel we still miss an important part of the puzzle. Why would accessing a class via an interface it implements be so much slower? The only difference I can see is that accessing a function via an Interface implies using virtual tables while the normally the functions can be called directly. To see whether this is the case I made a couple of changes to the above code. First I introduced two almost identical classes:

  public class VC
  {
     virtual public int f() { return 2; }
     virtual public int Count { get { return 200; } }

  }

  public class C
  {
      public int f() { return 2; }
      public int Count { get { return 200; } }

  }

As you can see VC is using virtual functions and C doesn’t. Now to DoOne and DoTwo:

    private static void DoOne()
      {  C a = new C();
         int s=0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < a.Count; c++) s += a.f();
         }

      }
      private static void DoTwo()
      {
           VC a = new VC();
         int s = 0;
         for (int j = 0; j < 100000; j++)
         {
            for (int c = 0; c < a.Count; c++) s +=  a.f();
         }

      }

And indeed:

DoOne took 0.01287789 seconds.
DoTwo took 8.982396 seconds.

This is even more scary – virtual function calls 800 times slower?? so a couple of question to the community:

  1. Can you reproduce? (given the
    fact that all had worse performance
    before, but not as bad as mine)
  2. Can you explain?
  3. (this may be the
    most important) – can you think of
    a way to avoid?

Boaz

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T18:31:27+00:00Added an answer on May 11, 2026 at 6:31 pm

    First I want to thank all for their answers. It was really essential in the path figuring our what was going on. Special thanks goes to @kentaromiura which found the key needed to get to the bottom of things.

    The source of the slow down of using List<T> via an IList<T> interface is the lack of the ability of the JIT complier to inline the Item property get function. The use of virtual tables caused by accessing the list through it’s IList interface prevents that from happening.

    As a proof , I have written the following code:

          public class VC
          {
             virtual public int f() { return 2; }
             virtual public int Count { get { return 200; } }
    
          }
    
          public class C
          {
             //[MethodImpl( MethodImplOptions.NoInlining)]
              public int f() { return 2; }
              public int Count 
              {
                // [MethodImpl(MethodImplOptions.NoInlining)] 
                get { return 200; } 
              }
    
          }
    

    and modified the DoOne and DoTwo classes to the following:

          private static void DoOne()
          {
             C c = new C();
             int s = 0;
             for (int j = 0; j < 100000; j++)
             {
                for (int i = 0; i < c.Count; i++) s += c.f();
             }
    
          }
          private static void DoTwo()
          {
             VC c = new VC();
             int s = 0;
             for (int j = 0; j < 100000; j++)
             {
                for (int i = 0; i < c.Count; i++) s += c.f();
             }
    
          }
    

    Sure enough the function times are now very similar to before:

     DoOne took 0.01273598 seconds.
     DoTwo took 8.524558 seconds.
    

    Now, if you remove the comments before the MethodImpl in the C class (forcing the JIT not to inline) – the timing becomes:

    DoOne took 8.734635 seconds.
    DoTwo took 8.887354 seconds.
    

    Voila – the methods take almost the same time. You can stil see that method DoOne is still slightly fast , which is consistent which the extra overhead of a virtual function.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've been doing some performance testing around the use of System.Diagnostics.Debug, and it seems
While doing some JavaScript performance tests I came up with the following piece of
I have a webapp that I am in the middle of doing some load/performance
I'm doing some performance-critical Python work and want to create a function that removes
We're currently looking into doing some performance tweaking on a website which relies heavily
I'm doing some performance testing of my app and noticed that it takes exceedingly
I've doing some performance analysis on the software I develop, and I've found that
Using SQL Server 2005. This is something I've noticed while doing some performance analysis.
I am doing some performance tests and noticed that a LINQ expression like result
We are doing some performance tests on our website and we are getting the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.