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

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T00:34:59+00:00 2026-05-20T00:34:59+00:00

Update : as I should have expected, the community’s sound advice in response to

  • 0

Update: as I should have expected, the community’s sound advice in response to this question was to “measure it and see.” chibacity posted an answer with some really nice tests that did this for me; meanwhile, I wrote a test of my own; and the performance difference I saw was actually so huge that I felt compelled to write a blog post about it.

However, I should also acknowledge Hans’s explanation that the ThreadStatic attribute is indeed not free and in fact relies on a CLR helper method to work its magic. This makes it far from obvious whether it would be an appropriate optimization to apply in any arbitrary case.

The good news for me is that, in my case, it seems to have made a big improvement.


I have a method which (among many other things) instantiates some medium-size arrays (~50 elements) for a few local variables.

After some profiling I’ve identified this method as something of a performance bottleneck. It isn’t that the method takes an extremely long time to call; rather, it is simply called many times, very quickly (hundreds of thousands to millions of times in a session, which will be several hours). So even relatively small improvements to its performance should be worthwhile.

It occurred to me that maybe instead of allocating a new array on each call, I could use fields marked [ThreadStatic]; whenever the method is called, it will check if the field is initialized on the current thread, and if not, initialize it. From that point on all calls on the same thread will have an array all ready to go at that point.

(The method initializes every element in the array itself, so having “stale” elements in the array should not be an issue.)

My question is simply this: does this seem like a good idea? Are there pitfalls to using the ThreadStatic attribute in this way (i.e., as a performance optimization to mitigate the cost of instantiating new objects for local variables) that I should know about? Is the performance of a ThreadStatic field itself perhaps not great; e.g., is there a lot of extra “stuff” happening in the background, with its own set of costs, to make this feature possible?

It’s also quite plausible to me that I’m wrong to even try to optimize something as cheap (?) as a 50-element array—and if that’s so, definitely let me know—but the general question still holds.

  • 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-20T00:35:00+00:00Added an answer on May 20, 2026 at 12:35 am

    I have carried out a simple benchmark and ThreadStatic performs better for the simple parameters described in the question.

    As with many algorithms which have a high number of iterations, I suspect it is a straightforward case of GC overhead killing it for the version which allocates new arrays:

    Update

    With tests that include an added iteration of the array to model minimal array reference use, plus ThreadStatic array reference usage in addition to previous test where reference was copied local:

    Iterations : 10,000,000
    
    Local ArrayRef          (- array iteration) : 330.17ms
    Local ArrayRef          (- array iteration) : 327.03ms
    Local ArrayRef          (- array iteration) : 1382.86ms
    Local ArrayRef          (- array iteration) : 1425.45ms
    Local ArrayRef          (- array iteration) : 1434.22ms
    TS    CopyArrayRefLocal (- array iteration) : 107.64ms
    TS    CopyArrayRefLocal (- array iteration) : 92.17ms
    TS    CopyArrayRefLocal (- array iteration) : 92.42ms
    TS    CopyArrayRefLocal (- array iteration) : 92.07ms
    TS    CopyArrayRefLocal (- array iteration) : 92.10ms
    Local ArrayRef          (+ array iteration) : 1740.51ms
    Local ArrayRef          (+ array iteration) : 1647.26ms
    Local ArrayRef          (+ array iteration) : 1639.80ms
    Local ArrayRef          (+ array iteration) : 1639.10ms
    Local ArrayRef          (+ array iteration) : 1646.56ms
    TS    CopyArrayRefLocal (+ array iteration) : 368.03ms
    TS    CopyArrayRefLocal (+ array iteration) : 367.19ms
    TS    CopyArrayRefLocal (+ array iteration) : 367.22ms
    TS    CopyArrayRefLocal (+ array iteration) : 368.20ms
    TS    CopyArrayRefLocal (+ array iteration) : 367.37ms
    TS    TSArrayRef        (+ array iteration) : 360.45ms
    TS    TSArrayRef        (+ array iteration) : 359.97ms
    TS    TSArrayRef        (+ array iteration) : 360.48ms
    TS    TSArrayRef        (+ array iteration) : 360.03ms
    TS    TSArrayRef        (+ array iteration) : 359.99ms
    

    Code:

    [ThreadStatic]
    private static int[] _array;
    
    [Test]
    public object measure_thread_static_performance()
    {
        const int TestIterations = 5;
        const int Iterations = (10 * 1000 * 1000);
        const int ArraySize = 50;
    
        Action<string, Action> time = (name, test) =>
        {
            for (int i = 0; i < TestIterations; i++)
            {
                TimeSpan elapsed = TimeTest(test, Iterations);
                Console.WriteLine("{0} : {1:F2}ms", name, elapsed.TotalMilliseconds);
            }
        };
    
        int[] array = null;
        int j = 0;
    
        Action test1 = () =>
        {
            array = new int[ArraySize];
        };
    
        Action test2 = () =>
        {
            array = _array ?? (_array = new int[ArraySize]);
        };
    
        Action test3 = () =>
        {
            array = new int[ArraySize];
    
            for (int i = 0; i < ArraySize; i++)
            {
                j = array[i];
            }
        };
    
        Action test4 = () =>
        {
            array = _array ?? (_array = new int[ArraySize]);
    
            for (int i = 0; i < ArraySize; i++)
            {
                j = array[i];
            }
        };
    
        Action test5 = () =>
        {
            array = _array ?? (_array = new int[ArraySize]);
    
            for (int i = 0; i < ArraySize; i++)
            {
                j = _array[i];
            }
        };
    
        Console.WriteLine("Iterations : {0:0,0}\r\n", Iterations);
        time("Local ArrayRef          (- array iteration)", test1);
        time("TS    CopyArrayRefLocal (- array iteration)", test2);
        time("Local ArrayRef          (+ array iteration)", test3);
        time("TS    CopyArrayRefLocal (+ array iteration)", test4);
        time("TS    TSArrayRef        (+ array iteration)", test5);
    
        Console.WriteLine(j);
    
        return array;
    }
    
    [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.GC.Collect")]
    private static TimeSpan TimeTest(Action action, int iterations)
    {
        Action gc = () =>
        {
            GC.Collect();
            GC.WaitForFullGCComplete();
        };
    
        Action empty = () => { };
    
        Stopwatch stopwatch1 = Stopwatch.StartNew();
    
        for (int j = 0; j < iterations; j++)
        {
            empty();
        }
    
        TimeSpan loopElapsed = stopwatch1.Elapsed;
    
        gc();
        action(); //JIT
        action(); //Optimize
    
        Stopwatch stopwatch2 = Stopwatch.StartNew();
    
        for (int j = 0; j < iterations; j++) action();
    
        gc();
    
        TimeSpan testElapsed = stopwatch2.Elapsed;
    
        return (testElapsed - loopElapsed);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

UPDATE: I should have mentioned in the original post that I want to learn
For my test I have the following: test should update holder do holder =
I have this code for update: public Boolean update() { try { data.put(ContactsContract.Groups.SHOULD_SYNC, true);
Update Added jsfiddle - see bottom of post I currently have a function that
Update: I have fixed this issue I have the following block of code which
I have a question regarding launching new activities. It boils down to this. I
Requirement : Should update MySQL database with that of MS Sql Server updates which
Is there a way to tell a JTable's row filter that it should update
I am trying to create Update trigger which should be invoked only if the
My code looks fine but it is not working as it should because update

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.