برچسب: instead

  • use Miniprofiler instead of Stopwatch to profile code performance | Code4IT

    use Miniprofiler instead of Stopwatch to profile code performance | Code4IT


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Do you need to tune up the performance of your code? You can create some StopWatch objects and store the execution times or rely on external libraries like MiniProfiler.

    Note: of course, we’re just talking about time duration, and not about memory usage!

    How to profile code using Stopwatch

    A Stopwatch object acts as a (guess what?) stopwatch.

    You can manually make it start and stop, and keep track of the elapsed time:

    Stopwatch sw = Stopwatch.StartNew();
    DoSomeOperations(100);
    var with100 = sw.ElapsedMilliseconds;
    
    
    sw.Restart();
    DoSomeOperations(2000);
    var with2000 = sw.ElapsedMilliseconds;
    
    sw.Stop();
    
    Console.WriteLine($"With 100: {with100}ms");
    Console.WriteLine($"With 2000: {with2000}ms");
    

    It’s useful, but you have to do it manually. There’s a better choice.

    How to profile code using MiniProfiler

    A good alternative is MiniProfiler: you can create a MiniProfiler object that holds all the info related to the current code execution. You then can add some Steps, which can have a name, and even nest them.

    Finally, you can print the result using RenderPlainText.

    MiniProfiler profiler = MiniProfiler.StartNew();
    
    using (profiler.Step("With 100"))
    {
        DoSomeOperations(100);
    }
    
    
    using (profiler.Step("With 2000"))
    {
        DoSomeOperations(2000);
    }
    
    Console.WriteLine(profiler.RenderPlainText());
    

    You won’t anymore stop and start any StopWatch instance.

    You can even use inline steps, to profile method execution and store its return value:

    var value = profiler.Inline(() => MethodThatReturnsSomething(12), "Get something");
    

    Here I decided to print the result on the Console. You can even create HTML reports, which are quite useful when profiling websites. You can read more here, where I experimented with MiniProfiler in a .NET API project.

    Here’s an example of what you can get:

    MiniProfiler API report

    Further readings

    We’ve actually already talked about MiniProfiler in an in-depth article you can find here:

    🔗 Profiling .NET code with MiniProfiler | Code4IT

    Which, oddly, is almost more detailed than the official documentation, that you can still find here:

    🔗 MiniProfiler for .NET | MiniProfiler

    Happy coding!

    🐧



    Source link

  • throw exceptions instead of returning null when there is no fallback | Code4IT

    throw exceptions instead of returning null when there is no fallback | Code4IT


    In case of unmanageable error, should you return null or throw exceptions?

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    When you don’t have any fallback operation to manage null values (eg: retry pattern), you should throw an exception instead of returning null.

    You will clean up your code and make sure that, if something cannot be fixed, it gets caught as soon as possible.

    Don’t return null or false

    Returning nulls impacts the readability of your code. The same happens for boolean results for operations. And you still have to catch other exceptions.

    Take this example:

    bool SaveOnFileSystem(ApiItem item)
    {
        // save on file system
        return false;
    }
    
    ApiItem GetItemFromAPI(string apiId)
    {
        var httpResponse = GetItem(apiId);
        if (httpResponse.StatusCode == 200)
        {
            return httpResponse.Content;
        }
        else
        {
            return null;
        }
    }
    
    DbItem GetItemFromDB()
    {
        // returns the item or null
        return null;
    }
    

    If all those methods complete successfully, they return an object (DbItem, ApiItem, or true); if they fail, they return null or false.

    How can you consume those methods?

    void Main()
    {
        var itemFromDB = GetItemFromDB();
        if (itemFromDB != null)
        {
            var itemFromAPI = GetItemFromAPI(itemFromDB.ApiId);
    
            if (itemFromAPI != null)
            {
                bool successfullySaved = SaveOnFileSystem(itemFromAPI);.
    
                if (successfullySaved)
                    Console.WriteLine("Saved");
            }
        }
        Console.WriteLine("Cannot save the item");
    }
    

    Note that there is nothing we can do in case something fails. So, do we really need all that nesting? We can do better!

    Throw Exceptions instead

    Let’s throw exceptions instead:

    void SaveOnFileSystem(ApiItem item)
    {
        // save on file system
        throw new FileSystemException("Cannot save item on file system");
    }
    
    
    ApiItem GetItemFromAPI(string apiId)
    {
        var httpResponse = GetItem(apiId);
        if (httpResponse.StatusCode == 200)
        {
            return httpResponse.Content;
        }
        else
        {
            throw new ApiException("Cannot download item");
        }
    }
    
    
    DbItem GetItemFromDB()
    {
        // returns the item or throws an exception
        throw new DbException("item not found");
    }
    

    Here, each method can complete in two statuses: it either completes successfully or it throws an exception of a type that tells us about the operation that failed.

    We can then consume the methods in this way:

    void Main()
    {
        try
        {
            var itemFromDB = GetItemFromDB();
            var itemFromAPI = GetItemFromAPI(itemFromDB.ApiId);
            SaveOnFileSystem(itemFromAPI);
            Console.WriteLine("Saved");
        }
        catch(Exception ex)
        {
            Console.WriteLine("Cannot save the item");
        }
    
    }
    

    Now the reader does not have to spend time reading the nested operations, it’s all more linear and immediate.

    Conclusion

    Remember, this way of writing code should be used only when you cannot do anything if an operation failed. You should use exceptions carefully!

    Now, a question for you: if you need more statuses as a return type of those methods (so, not only “success” and “fail”, but also some other status like “partially succeeded”), how would you transform that code?

    Happy coding!

    🐧



    Source link