Encryption Project: Need advice on how to eliminate method overhead

330 Views Asked by At

I am looking for advice. I have developed my own encryption algorithms because I enjoy it and I can. Now, I am looking to try a new idea.

My idea involves consolidating a number my algorithms into a larger one. For instance, you call X.Encrypt() then it uses A.Encrypt(), B.Encrypt(), C.Encrypt() etc. When you perform this kind of operation one byte per A, B, C method call the method overhead becomes killer. Going from a few ms to several minutes. So, any questions?

I am merely looking for code design tips and tricks to maybe lessen the issue.

Thanks ahead of time.

Update

Code example of the issue:

//fast
moduleA.Transform(true, buffer, 0, buffer.Length);
moduleB.Transform(true, buffer, 0, buffer.Length);

//slow
for (int L = 0; L < buffer.Length; )
{
    moduleA.Transform(true, buffer, L++, 1);
    moduleB.Transform(true, buffer, L++, 1);
}

I know this problem is inherent to how it is being called. My goal is to change how I am doing it. I know inside the Transform methods there can be improvement. The fast operates in about 24s while the slow takes many minutes. Clearly, overhead from the methods, no profiler needed :)

I do have an idea I am going to try. I am thinking about using "run-modes" where I instead of looping outside of the Transform methods I change how it runs inside each method to fit my needs. So, I could do an every-other-byte encryption performed inside the Transform methods and as a batch. I believe this would eliminate the overhead I am getting.

FINAL UPDATE (Solved my own issue, still open to ideas!)

Incrementing the loop rate inside the Transform method has worked!

What I've done is the following and it seems to work well:

ITransformationModule moduleA = TransformationFactory.GetModuleInstance("Subspace28");
ITransformationModule moduleB = TransformationFactory.GetModuleInstance("Ataxia");
moduleA.IncrementInterval = 2;
moduleB.IncrementInterval = 2;
moduleA.Transform(true, buffer, 0, buffer.Length);
moduleB.Transform(true, buffer, 1, buffer.Length);

This runs at about 12s for 100MB on my work VM. Thank you all who contributed! It was a combination of response that helped lead me to try it this way. I appreciate you all greatly!

This is just proof of concept at the moment. It is building towards greater things! :)

5

There are 5 best solutions below

3
On

You could try to implement your algorithm such that your code makes chunky calls then chatty calls. That is instead of calling functions hundred of time, you could have less function calls such that each function has more work to do. This is one advice, you might have to make your algorithm efficient as well such that its not processor intensive. Hope this help.

0
On

You want to have class X call methods from class A, B, C, D, E, F, G, etc...without the method call overhead. At first, that seems absurd. You might be able to find a way to do it using System.Reflection.Emit. That is, dynamically create a method that does A+B+C+D+E+F+G, then call that.

3
On

Are you encrypting the data by calling methods on a byte-by-byte basis? Why not call the method on a chunk of data and loop within that method? Also, while it is definitely fun to try out your own encryption methods, you should pretty much always use a known, tested, and secure algorithm if security is at all a concern.

0
On

Firstly profile your code so you know where you should operate first, then ask again :)

2
On

Would something like this work? Of course you would have to modify it to fit your encryption arguments and return types....

static class Encryptor
{
    delegate void Transform(bool b, byte[] buffer, int index, int length);
    static Transform[] transformers = new Transform[3];

    static Encryptor()
    {
        transformers[0] = (b, buffer, index, length) => { /*Method A*/ };
        transformers[1] = (b, buffer, index, length) => { /*Method B*/ };
        transformers[2] = (b, buffer, index, length) => { /*Method C*/ };
    }

    public static void Encrypt(bool b, byte[] buffer)
    {
        int length = buffer.Length;
        int nTransforms = transformers.Length;
        for (int i = 0; i < length;)
        {
            for (int j = 0; j < nTransforms; j++)
            {
                transformers[i % nTransforms](b, buffer, i++, 1);
            }
        }
    }
}

Edit So this would do the second example

Encryptor.Encrypt(yourBoolean, yourBuffer);

I don't know the specifics of your implementation, but this shouldn't have overhead issues.