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 9206649
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T00:13:12+00:00 2026-06-18T00:13:12+00:00

I’m working on a proxy and for generic classes with a reference type parameter

  • 0

I’m working on a proxy and for generic classes with a reference type parameter it was very slow. Especially for generic methods (about 400 ms vs 3200 ms for trivial generic methods that just returned null). I decided to try to see how it would perform if I rewrote the generated class in C#, and it performed much better, about the same performance as my non-generic class code.

Here is the C# class I wrote:: (note I changed by naming scheme but not a heck of a lot)::

namespace TestData
{
    public class TestClassProxy<pR> : TestClass<pR>
    {
        private InvocationHandler<Func<TestClass<pR>, object>> _0_Test;
        private InvocationHandler<Func<TestClass<pR>, pR, GenericToken, object>> _1_Test;
        private static readonly InvocationHandler[] _proxy_handlers = new InvocationHandler[] { 
            new InvocationHandler<Func<TestClass<pR>, object>>(new Func<TestClass<pR>, object>(TestClassProxy<pR>.s_0_Test)), 
        new GenericInvocationHandler<Func<TestClass<pR>, pR, GenericToken, object>>(typeof(TestClassProxy<pR>), "s_1_Test") };



        public TestClassProxy(InvocationHandler[] handlers)
        {
            if (handlers == null)
            {
                throw new ArgumentNullException("handlers");
            }
            if (handlers.Length != 2)
            {
                throw new ArgumentException("Handlers needs to be an array of 2 parameters.", "handlers");
            }
            this._0_Test = (InvocationHandler<Func<TestClass<pR>, object>>)(handlers[0] ?? _proxy_handlers[0]);
            this._1_Test = (InvocationHandler<Func<TestClass<pR>, pR, GenericToken, object>>)(handlers[1] ?? _proxy_handlers[1]);
        }


        private object __0__Test()
        {
            return base.Test();
        }

        private object __1__Test<T>(pR local1) where T:IConvertible
        {
            return base.Test<T>(local1);
        }

        public static object s_0_Test(TestClass<pR> class1)
        {
            return ((TestClassProxy<pR>)class1).__0__Test();
        }

        public static object s_1_Test<T>(TestClass<pR> class1, pR local1) where T:IConvertible
        {
            return ((TestClassProxy<pR>)class1).__1__Test<T>(local1);
        }

        public override object Test()
        {
            return this._0_Test.Target(this);
        }

        public override object Test<T>(pR local1)
        {
             return this._1_Test.Target(this, local1, GenericToken<T>.Token);
        }
    }
}

This is compiles in release mode to the same IL as my generated proxy here is the class that its proxying::

namespace TestData
{
    public class TestClass<R>
    {
        public virtual object Test()
        {
            return default(object);
        }

        public virtual object Test<T>(R r) where T:IConvertible
        {
            return default(object);
        }
    }
}

There was one-exception, I was not setting the beforefieldinit attribute on the type generated. I was just setting the following attributes::public auto ansi

Why did using beforefieldinit make the performance improve so much?

(The only other difference was I wasn’t naming my parameters which really didn’t matter in the grand scheme of things.
The names for methods and fields are scrambled to avoid collision with real methods.
GenericToken and InvocationHandlers are implementation details that are irrelevant for sake of argument.
GenericToken is literally used as just a typed data holder as it allows me to send “T” to the handler

InvocationHandler is just a holder for the delegate field target there is no actual implementation detail.

GenericInvocationHandler uses a callsite technique like the DLR to rewrite the delegate as needed to handle the different generic arguments passed
)

EDIT::
Here is the test harness::

private static void RunTests(int count = 1 << 24, bool displayResults = true)
{
    var tests = Array.FindAll(Tests, t => t != null);
    var maxLength = tests.Select(x => GetMethodName(x.Method).Length).Max();

    for (int j = 0; j < tests.Length; j++)
    {
        var action = tests[j];
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < count; i++)
        {
            action();
        }
        sw.Stop();
        if (displayResults)
        {
            Console.WriteLine("{2}  {0}: {1}ms", GetMethodName(action.Method).PadRight(maxLength),
                              ((int)sw.ElapsedMilliseconds).ToString(), j);
        }
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }
}

private static string GetMethodName(MethodInfo method)
{
    return method.IsGenericMethod
            ? string.Format(@"{0}<{1}>", method.Name, string.Join<Type>(",", method.GetGenericArguments()))
            : method.Name;
}

And in a test I do the following::

Tests[0] = () => proxiedTestClass.Test();
Tests[1] = () => proxiedTestClass.Test<string>("2");
Tests[2] = () => handClass.Test();
Tests[3] = () => handClass.Test<string>("2");
RunTests(100, false);
RunTests();

Where Tests is a Func<object>[20], and proxiedTestClass is the class generated by my assembly, and handClass is the one I generated by hand.
RunTests is called twice, once to “warm” things up, and again to run it and print to the screen. I mostly took this code from a post here by Jon Skeet.

  • 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-06-18T00:13:14+00:00Added an answer on June 18, 2026 at 12:13 am

    As stated in ECMA-335 (CLI cpecification), part I, section 8.9.5:

    The semantics of when and what triggers execution of such type
    initialization methods, is as follows:

    1. A type can have a type-initializer method, or not.
    2. A type can be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed
      semantic BeforeFieldInit).
    3. If marked BeforeFieldInit then the type’s initializer method is executed at, or sometime before, first access to any static field
      defined for that type.
    4. If not marked BeforeFieldInit then that type’s initializer method is executed at (i.e., is triggered by):

      a. first access to any static field of that type, or

      b. first invocation of any static method of that type, or

      c. first invocation of any instance or virtual method of that type
      if it is a value type or

      d. first invocation of any constructor for that type.

    Also, as you can see from the Michael’s code above, the TestClassProxy has only one static field: _proxy_handlers. Notice, that it is used only two times:

    1. In the instance constructor
    2. And in the static field initializer itself

    So when BeforeFieldInit is specified, type-initializer will be called only once: in the instance constructor, right before the first access to _proxy_handlers.

    But if BeforeFieldInit is omitted, CLR will place the call to the type-initializer before every TestClassProxy's static method invocation, static field access, etc.

    In particular, the type-initializer will be called on every invocation of s_0_Test and s_1_Test<T> static methods.

    Of course, as stated in ECMA-334 (C# Language Specification), section 17.11:

    The static constructor for a non-generic class executes at most once
    in a given application domain. The static constructor for a generic
    class declaration executes at most once for each closed constructed
    type constructed from the class declaration (§25.1.5).

    But in order to guarantee this, CLR have to check (in a thread-safe manner) if the class is already initialized, or not.

    And these checks will decrease the performance.

    PS: You might be surprised that performance issues will gone once you change s_0_Test and s_1_Test<T> to be instance-methods.

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

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I don't have much knowledge about the IPv6 protocol, so sorry if the question
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
I'm working with an upstream system that sometimes sends me text destined for HTML/XML
Let's say I'm outputting a post title and in our database, it's Hello Y&#8217;all
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I am reading a book about Javascript and jQuery and using one of the
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
That's pretty much it. I'm using Nokogiri to scrape a web page what has

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.