1

I have written an application in C# that generates all the words that can be existed in the combination of alphabets, numbers and few special characters.

The problem is that it isn't memory efficient as it is adapting Recursion and also some collection like List.

Is there any way I can make it to run in limited memory environment?

Umair

3
  • 4
    Well, let's see what you have.. Commented Jul 28, 2010 at 22:18
  • Recursion can be quite neat when dealing with trees, graphs. Commented Jul 28, 2010 at 22:23
  • @Hamish Recursion can be neat yes, but not in the context of this question. Straight recursion potentially needs lots of stack space and lots of stack frame "pushing and poppin". The name of this very site has an association with this scenario... Commented Jul 28, 2010 at 22:44

5 Answers 5

7

Convert it to an iterative function.

Sign up to request clarification or add additional context in comments.

5 Comments

The key to writing memory efficient recursive algorithms is limiting the amount of data on the stack. When you can't do that, the only real solution is to switch to iteration.
Depends. if you're using stack space to maintain state, just switching to iteration won't help. you'll have to restructure your algorithm somehow. if it's using stack space because you have a tail call that the compiler isn't optimizing, then ya switching to iteration will do it, altho I'd blame the compiler in that case.
agree as well. recursion only scales if your compiler is built to optimize for it (like throwing away the old stack when facing tail-recursion, ie the recursive call being the last thing a function does, something LISP eg really appreciates)
in this case i believe the poster is storing all his results in a list, meaning he has ~68^8 ~= 450000000000000 * 8 bytes of memory he's trying to use.
Haha, the solution would be to dump the results to some sort of archiver class, which will then decide when is a good time to write another file and what it's name should be.
0

Well, you obviously cannot store the intermediate results in memory (unless you've got some sort of absurd computer at your disposal); you will have to write the results to disk.

The recursion depth isn't a result of the number of considered characters - its determined by what the maximum string length you're willing to consider.

For instance, my install of python 2.6.2 has it's default recursion limit set to 1000. Arguable, I should be able to generate all possible 1-1000 length strings given a character set within this limitation (now, I think the recursion limit applies to total stack depth, so the actual limit may be less than 1000).

Edit (added python sample): The following python snippet will produce what you're asking for (limiting itself to the given runtime stack limits):

from string import ascii_lowercase

def generate(base="", charset=ascii_lowercase):
    for c in charset:
        next = base + c
        yield next
        try:
            for s in generate(next, charset):
                yield s
        except:
            continue

for s in generate():
    print s

One could produce essentially the same in C# by try/catching on StackOverflowException. As I'm typing this update, the script is running, chewing up one of my cores. However, memory usage is constant at less than 7MB. Now, I'm only print to stdout since I'm not interested in capturing the result, but I think it proves the point above. ;)

Addendum to the example: Interesting note: Looking closer at running processes, python is actually I/O bound with the above example. It's only using 7% of my CPU, while the rest of the core is bound rending the results in my command window. Minimizing the window allows python to climb to 40% of total CPU usage, this is on a 2 core machine.

Comments

0

One more consideration: When you concatenate or use some other method to generate a string in C#, it occupies its own memory and may stick around for a while. If you are generating millions of strings, you are likely to notice some performance drag.

If you don't need to keep your many strings around, I would see if there's away to avoid generating the strings. For example, maybe you have a character array that you keep updating as you move through the character combinations, and if you're outputting them to a file, you would output them one character at a time so you don't have to build the string.

Comments

0

Well...I am not sure whom with I go amongst you but I got the solution. I am using more than one process one that is interacting with user and other for finding the words combination. The other process finds 5000 words, save them and quit. Communication is being achieved through WCF. This looks pretty fine as when process quits = frees memory.

Comments

0

Unfortunately C# compiler does not perform tail call optimization, which is something that you want to happen in this case. CLR supports it, kinda, but you shouldn't rely on it.

Perhaps left of field, but maybe you can write the recursive part of your program in F#? This way you can leverage guaranteed tail call optimization and reuse bits of your C# code. Whilst a steep learning curve, F# is a more suitable language for these combinatorial tasks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.