Home > Back-end >  Compile C# code once and execute it multiple times in python
Compile C# code once and execute it multiple times in python

Time:10-24

I'm getting weird numbers on my C# sorting algorithm times that I think is caused by python recompiling the code every loop. How can I change this function to compile the C# code once and then execute the same compilation with different command line arguments? Is that even possible? In theory the code should follow a curve similar to the rest of the languages being tested.

def runCSharp(debug):
    
    for size in range(1000, 10001, 1000):
        if debug:
            print("Beginning to sort", size, " integers")
            
        # Start the clock
        tic = time.time()

        # Run the C# script BubbleSort.cs in the CSharp folder
        args = ['dotnet', 'run', str(size)]
        p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', cwd="CSharp")
        
        output, err = p.communicate()
        if debug:
            print(output)
            print(err)
            print("C# Bubble Sort finished in %0.6f seconds" % (toc - tic))

        toc = time.time()
        csharpTimes.append(toc-tic)

    return csharpTimes

For completeness's sake, this is my C# code, although it sorts fine and something besides my sort implementation is likely the culprit.

using System;
using System.IO;
class BubbleSort
{
    static void Main(string[] args)
    {
        int length;
        StreamReader reader;

        if (args.Length > 0)
        {
            length = Convert.ToInt32(args[0]);
            reader = new StreamReader(@"..\numbers.txt");
        }
        else
        {
            length = 10000;
            reader = new StreamReader(@"..\..\..\..\numbers.txt");
        }

        Console.WriteLine("Sorting {0} numbers (C#)", length);

        int[] array = new int[length];

        
        for (int i = 0; i < length; i  )
        {
            array[i] = Convert.ToInt32(reader.ReadLine());
        }
        
        bool sorted = false;
        while (!sorted)
        {
            sorted = true;
            for (int i = 0; i < length - 1; i  )
            {
                if (array[i] > array[i   1])
                {
                    int temp = array[i];
                    array[i] = array[i   1];
                    array[i   1] = temp;
                    sorted = false;
                }
            }
        }
        // Print the first and last ten numbers from the array to the console
        for (int i = 0; i < 10; i  )
        {
            Console.WriteLine(array[i]);
        }
        for (int i = length - 10; i < length; i  )
        {
            Console.WriteLine(array[i]);
        }
    }
}

CodePudding user response:

Because you compile the C# code every time by dotnet run. Check out dotnet run options to find something which prevents build.

CodePudding user response:

The suggestions by @Rezaeimh7 and @jeremy-lakeman to use --no-build did provide a flat speed boost compared to the original code, but that wasn't really what I was after.

What I ended up doing was building once at the beginning of the function with

args = ['dotnet', 'build', 'CSharp']

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')

and then for running the code I would point directly at the generated executable, cutting out the dotnet entirely with

args = [r'CSharp\bin\Debug\net6.0\CSharp', str(size)]

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')

Which generated the smoother curve I was looking for.

  • Related