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

  • Home
  • SEARCH
  • 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 7193839
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T20:15:04+00:00 2026-05-28T20:15:04+00:00

Following code is simplified version of the code that I am trying to optimize.

  • 0

Following code is simplified version of the code that I am trying to optimize.

void Main()
{
    var words = new List<string> {"abcd", "wxyz", "1234"};

    foreach (var character in SplitItOut(words))
    {
        Console.WriteLine (character);
    }
}

public IEnumerable<char> SplitItOut(IEnumerable<string> words)
{
    foreach (string word in words)
    {
        var characters = GetCharacters(word);

        foreach (char c in characters)
        {
            yield return c;
        }
    }
}

char[] GetCharacters(string word)
{
    Thread.Sleep(5000);
    return word.ToCharArray();
}

I cannot change the signature of method SplitItOut.The GetCharacters method is expensive to call but is thread safe. The input to SplitItOut method can contain 100,000+ entries and a single call to GetCharacters() method can take around 200ms. It can also throw exceptions which I can ignore. Order of the results do not matter.

In my first attempt I came up with following implementation using TPL which speeds up the things quite a bit, but is blocking till I am done processing all the words.

public IEnumerable<char> SplitItOut(IEnumerable<string> words)
{
    Task<char[][]> tasks = Task<char[][]>.Factory.StartNew(() =>
    {
        ConcurrentBag<char[]> taskResults = new ConcurrentBag<char[]>();

        Parallel.ForEach(words,
            word => 
            {
                taskResults.Add(GetCharacters(word));
            });

        return taskResults.ToArray();
    });

    foreach (var wordResult in tasks.Result)
    {
        foreach (var c in wordResult)
        {
            yield return c;
        }
    }
}

I am looking for any better implementation for method SplitItOut() than this. Lower processing time is my priority here.

  • 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-28T20:15:05+00:00Added an answer on May 28, 2026 at 8:15 pm

    If I’m reading your question correctly, you’re not looking to just speed up the parallel processing that creates the chars from the words – you would like your enumerable to produce each one as soon as it’s ready. With the implementation you currently have (and the other answers I currently see), the SplitItOut will wait until all of the words have been sent to GetCharacters, and all results returned before producing the first one.

    In cases like this, I like to think of things as splitting my process into producers and a consumer. Your producer thread(s) will take the available words and call GetCharacters, then dump the results somewhere. The consumer will yield up characters to the caller of SplitItOut as soon as they are ready. Really, the consumer is the caller of SplitItOut.

    We can make use of the BlockingCollection as both a way to yield up the characters, and as the “somewhere” to put the results. We can use the ConcurrentBag as a place to put the words that have yet to be split:

    static void Main()
            {
                var words = new List<string> { "abcd", "wxyz", "1234"};
    
                foreach (var character in SplitItOut(words))
                {
                    Console.WriteLine(character);
                }
            }
    
    
            static char[] GetCharacters(string word)
            {
                Thread.Sleep(5000);
                return word.ToCharArray();
            }
    

    No changes to your main or GetCharacters – since these represent your constraints (can’t change caller, can’t change expensive operation)

            public static IEnumerable<char> SplitItOut(IEnumerable<string> words)
            {
                var source = new ConcurrentBag<string>(words);
                var chars = new BlockingCollection<char>();
    
                var tasks = new[]
                       {
                           Task.Factory.StartNew(() => CharProducer(source, chars)),
                           Task.Factory.StartNew(() => CharProducer(source, chars)),
                           //add more, tweak away, or use a factory to create tasks.
                           //measure before you simply add more!
                       };
    
                Task.Factory.ContinueWhenAll(tasks, t => chars.CompleteAdding());
    
                return chars.GetConsumingEnumerable();
            }
    

    Here, we change the SplitItOut method to do four things:

    1. Initialize a concurrentbag with all of the words we wish to split. (side note: If you want to enumerate over words on demand, you can start a new task to push them in rather than doing it in the constructor)
    2. Start up our char “producer” Tasks. You can start a set number, use a factory, whatever. I suggest not going task-crazy before you measure.
    3. Signal the BlockingCollection that we are done when all tasks have completed.
    4. “Consume” all of the produced chars (we make it easy on ourselves and just return an IEnumerable<char> rather than foreach and yield, but you could do it the long way if you wish)

    All that’s missing is our producer implementation. I’ve expanded out all the linq shortcuts to make it clear, but it’s super simple:

            private static void CharProducer(ConcurrentBag<string> words, BlockingCollection<char> output)
            {
                while(!words.IsEmpty)
                {
                    string word;
                    if(words.TryTake(out word))
                    {
                        foreach (var c in GetCharacters(word))
                        {
                            output.Add(c);
                        }
                    }
                }
            }
    

    This simply

    1. Takes a word out of the ConcurrentBag (unless it’s empty – if it is, task is done!)
    2. Calls the expensive method
    3. Puts the output in the BlockingCollection
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The following code snippet is a simplified version of my issue. Basically I'm trying
The following code is a simplified version of what I use for event dispatching.
I am debugging some code and have encountered the following SQL query (simplified version):
The following code is the simplified version of my problem: public partial class Form1
The following (simplified version of our) code passes our JUnit tests under Hibernate, but
I have the following C++ code (simplified version): class Shape { bool isCircle =
I was trying to make a simplified version of my code for this question
The following code works: List<JsonStock> stock = new List<JsonStock>(); foreach(tblStock item in repository.Single(id).tblStocks) stock.Add((JsonStock)
Imagine I have the following code (simplified regarding my real context of course): <div
I'm using gcc 4.3.2. I have the following code (simplified): #include <cstdlib> template<int SIZE>

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.