How much async/await is OK? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
In our project we are using async/await for almost 3 purposes (for all of their methods):
Data access layer: where fetching/updating databases (using Dapper).
Cache (Redis): read/write.
ASP.Net MVC 5 controllers.
The question is how much async/await is ok. Is it ok to use them even when reading or writing small amount of data? How about cache and controllers?
Remarks: the project is a little special and it may have about 50,000 requests per second for few hours of a day.

According to an article I've read:
Async/await is great for avoiding blocking while potentially
time-consuming work is performed in a .NET application, but there are
overheads associated with running an async method
The cost of this is comparatively negligible when the asynchronous
work takes a long time, but it’s worth keeping in mind.
Based on what you asked, even when reading or writing small amount of data?. It doesnt seem to be a good idea as there are over.
Here is the article: The overhead of async/await in NET 4.5
And in the article he used a profiler to check the optimization of async/await.
QUOTE:
Despite this async method being relatively simple, ANTS Performance
Profiler shows that it’s caused over 900 framework methods to be run
in order to initialize it and the work it does the first time that
it’s run.
The question here maybe if you're gonna accept these minimal overheads, and take into consideration that these overheads do pile up into something possibly problematic.

The question is how much async/await is ok. Is it ok to use them even
when reading or writing small amount of data? How about cache and
controllers?
You should use async/await for I/O bound operations, it doesn't matter if it's a small amount of data. More important is to avoid potentially long running I/O bound operations mainly disk and network calls. Asp.net has limited size of thread pool and these operations may block it. Using asynchronous calls helps your application to scale better and allows to handle more concurrent requests.
For more info: http://msdn.microsoft.com/en-us/magazine/dn802603.aspx

Related

Parallel processing in server applications [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Since on a server side application the work is done by the server, and since it also needs to serve other request, I would like to know if there are any real benefits of using Parallel processing in server side applications? The way I see it, I think it is usually bad to use parallel-processing? focusing the CPU power only on part of the problem, other requests cannot get server?
If there are advantages, I guess they should be considered only when specific conditions are meat. So, what are some good guidelines of when to use the Parallel class in server applications ?
You are balancing two concerns: Fast response for a given user, and supporting all users that wish to connect to the server in a given time period.
Before considering parallelism for faster computation for a given user, consider whether precomputation and caching allow you to meet your performance requirements. Perform hotspot analysis and see if there are opportunities to optimize existing code.
If your deployment hardware is a given, observe the CPU load during peak times. If the CPU is busy (rule of thumb 70%+ utilization), parallel computing will be detrimental to both concerns. If the CPU isn't heavily loaded, you might improve response time for a given user without affecting the number of users the server can handle at once (benchmark to be sure).
If you aren't meeting your single-user performance targets and have exhausted options to precalculate and cache (and have analyzed performance hotspots and don't see opportunities to optimize), you can always parallelize workloads that lend themselves to parallel computation if you're willing to upgrade your server(s) as needed so that during peak periods you don't over-tax the CPU.
As with most performance-related questions: it depends on a lot of factors. Things like:
do you tend to have a lot of requests hitting your server at the same time?
how much of a typical request's turnaround time is spent waiting on I/O, as opposed to actually exercising the CPU?
are you able to have multiple instances of your server code sitting behind a load balancer?
how well does the operation you're looking at get optimized by parallelizing?
how important is it for the operation you're performing to return an answer to the user faster than it would without parallelism?
In my experience, most of the time for typical request is spent waiting for things like database queries and REST API calls to complete, or loading files from a disk. These are not CPU-intensive operations, and inasmuch as they can be made concurrent that can usually be done by simply orchestrating async Tasks in a concurrent manner, not necessarily using parallel threads.
Also in my experience, most attempts to use the TPL to improve performance of an algorithm end up yielding only marginal performance improvements, whereas other approaches (like using more appropriate data structures, caching, etc.) often yield improvements of orders of magnitude.
And of course if your application isn't going too slow for your needs in the first place then any optimization would count as premature optimization, which you want to avoid.
But if you for some reason find yourself doing a CPU-intensive operation that responds well to parallelism, in a part of your code that absolutely must perform faster than it currently does, then parallel processing is a good choice.

Async rewrite of sync code performs 20 times slower in loops [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm trying not to panic here, so please, bear with me! :S
I've spent a considerable amount of time rewriting a big chunk of code from sync (i.e. thread-blocking) to async (i.e. C# 6+). The code in question runs inside an ASP.NET application and spans everything from low-level ADO.NET DB access to higher-level unit-of-work pattern, and finally a custom async HTTP handler for public API access - the full server-side stack, so to speak. The primary purpose of the rewrite wasn't optimization, but untangling, general clean-up, and bringing the code up to something that resembles a modern and deliberate design. Naturally, optimization gain was implicitly assumed.
Everything in general is great and I'm very satisfied with the overall quality of the new code, as well as the improved scalability it's shown so far in the last couple of weeks of real-world tests. The CPU and memory loads on the server have fallen drastically!
So what's the problem, you might ask?
Well, I've recently been tasked with optimizing a simple data import that is still utilizing the old sync code. Naturally, it didn't take me long before I tried changing it to the new async code-base to see what would happen.
Given everything, the import code is quite simple. It's basically a loop that reads items from a list that's been previously read into memory, adds each of them individually to a unit of work, and saves it to a SQL database by means of an INSERT statement. After the loop is done, the unit of work is committed, which makes the changes permanent (i.e. the DB transaction is committed as well).
The problem is that the new code takes about 20 times as long as the old one, when the expectation was quite the opposite! I've checked and double-checked and there is no obvious overhead in the new code that would warrant such sluggishness.
To be specific: the old code is able to import 1100 items/sec steadily, while the new one manages 40 items/sec AT BEST (on average, it's even less, because the rate is falling slightly over time)! If I run the same test over a VPN, so that the network cost outweighs everything else, the throughputs is somewhere along 25 items/sec for sync and 20 for async.
I've read about multiple cases here on SO which report a 10-20% slowdown when switching from sync to async in similar situations and I was prepared to deal with that for tight loops such as mine. But a 20-fold penalty in a non-networked scenario?! That's completely unacceptable!
What is my best course of action here? How do I tackle this unexpected problem?
UPDATE
I've run the import under a profiler, as suggested.
I'm not sure what to make of the results, though. It would seem that the process spends more than 80% of its time just... waiting. See for yourselves:
The 14% spent inside the custom HTTP handler corresponds to the IDataReader.Read which is a consequence of a tiny remainder of the old sync API. This is still subject to optimization and is likely to be reduced in the near future. Regardless, it's dwarfed by the WaitAny cost, which definitely isn't there in the all-sync version!
What's curious is that the report isn't showing any direct calls from my code to WaitAny, which makes me think this is probably part of the async/await infrastructure. Am I wrong in this conclusion? I kind of hope I am!
What worries me is that I might be reading this all wrong. I know that async costs are much harder to reason about than single-threaded costs. In the end, the WaitAny might be nothing more than the equivalent of the "Sytem Idle Process" on Windows - an artificial representation of the CPU infrastructure that reflects a free percentage of the CPU resource.
Can anyone shed some light here for me, please?

Worse multithreaded performance on better system (possibly due to Deedle) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
We are dealing with a multithreaded C# service using Deedle. Tests on a quad-core current system versus an octa-core target system show that the service is about two times slower on the target system instead of two times faster. Even when restricting the number of threads to two, the target system is still almost 40% slower.
Analysis shows a lot of waiting in Deedle(/F#), making the target system basically run on two core. Non-Deedle test programs show normal behaviour and superiour memory bandwidth on the target system.
Any ideas on what could cause this or how to best approach this situation?
EDIT: It seems most of the time waiting is done in calls to Invoke.
The problem turned out to be a combination of using Windows 7, .NET 4.5 (or actually the 4.0 runtime) and the heavy use of tail recursion in F#/Deedle.
Using Visual Studio's Concurrency Visualizer, I already found that most time is spent waiting in Invoke calls. On closer inspection, these result in the following call trace:
ntdll.dll:RtlEnterCriticalSection
ntdll.dll:RtlpLookupDynamicFunctionEntry
ntdll.dll:RtlLookupFunctionEntry
clr.dll:JIT_TailCall
<some Deedle/F# thing>.Invoke
Searching for these function gave multiple articles and forum threads indicating that using F# can result in a lot of calls to JIT_TailCall and that .NET 4.6 has a new JIT compiler that seems to deal with some issues relating to these calls. Although I didn't find anything mentioning problems relating to locking/synchronisation, this did give me the idea that updating to .NET 4.6 might be a solution.
However, on my own Windows 8.1 system that also uses .NET 4.5, the problem doesn't occur. After searching a bit for similar Invoke calls, I found that the call trace on this system looked as follows:
ntdll.dll:RtlAcquireSRWLockShared
ntdll.dll:RtlpLookupDynamicFunctionEntry
ntdll.dll:RtlLookupFunctionEntry
clr.dll:JIT_TailCall
<some Deedle/F# thing>.Invoke
Apparently, in Windows 8(.1) the locking mechanism was changed to something less strict, which resulted in a lot less need for waiting for the lock.
So only with the target system's combination of both Windows 7's strict locking and .NET 4.5's less efficient JIT compiler, did F#'s heavy usage of tail recursion cause problems. After updating to .NET 4.6, the problem disappeared and our service is running as expected.

Is it acceptable to cache huge amount of data in .Net? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm designing an accounting application with more than 400 tables in SQL Server.
About 10% of those tables are operational tables, and the others are used for decoding and reference information.
For example, Invoice tables (Master and details) use about 10 table to decode information like buyer, item , marketer and ... .
I want to know is it acceptable to cache decode tables in asp.net cache and do not query them from SQL Server (I know that changes to cache items should commit on SQL Server too). And use cache items for decoding?
I think it makes it so much faster than regular applications.
Maybe all of them together(Cache tables) are about 500 MB after some years because they don't change frequently.
If you've got the RAM then it's fine to use 500 MB.
However unless you have a performance problem now then caching will only cause problems. Don't fix problems that you haven't encountered, design for performance and optimize only when you have problems - because otherwise the optimization can cause more problems that it solves.
So I would advise that usually it is better to ensure that your queries are optimized and well structured, you have the correct indexes on the tables and that you issue a minimum amount of queries.
Although 500MB isn't a lot of data to cache, with all due respect, usually SQL Server will do a better job of caching than you can - providing that you use it correctly.
Using a cache will always improve performance; at a cost of higher implementation complexity.
For static data that never changes a cache is useful; but it still needs to be loaded and shared between threads which in itself can present challenges.
For data that rarely changes it becomes much more complex simply because it could have changed. If a single application (process) is the only updater of a cache then it isn't as difficult, but still not a simple task.
I have spent months optimizing a offline batch processing system (where the code has complete control of the database for a period of 12 hours). Part of the optimisation is to use various caches and data reprojections. All of the caches are readonly. Memory usage is around the 10gb mark during execution, database is around 170gb, 60 million records.
Even with the caching there has been considerable changes to the underlying schema to improve efficiency. The readonly caches are to eliminate reading during processing; to allow multi threaded processing and to improve the insert performance.
Processing rate has gone from 6 items processed per second 20 months ago to around 6000 items per second (yesterday) - but there is a genuine need for this optimization as the number of items to process has risen from 100,000 to 8 million in the same period.
If you don't have a need then don't optimize.

How should I optimize following requirement in my application. Dealing mainly with asp.net 3.5, C#, File I/O, Threading and some other aspects as well [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Scenario -
It is an simple application through which only single user ( NO Authentication Reqd.) uploads only excel 2003/2010 file one at a time and then two functions are called Foo() & Goo() one after other taking some data from that excel doing some string manipulation & numeric computation returning two different text files for same user to download.
Now my question is how can I optimize this. Performance has high preference. Also how can I use Threading between those two functions Foo() & Goo() ? Will that optimize my performance ?
What more tips & tweaks are needed to achieve maximum speed in overall process.
Do the results of Goo depend on anything done in Foo? Do either of the methods actually change the data in the Excel document? Do they need to use the Excel object model other than to extract data to start with?
If not, you could:
Extract the data needed for Foo, then launch Foo in a separate thread
Extract the data needed for Goo and then run Goo (in the current thread, as it's already separate)
However, I would look at the existing performance characteristics of your code first - which bits actually take the most time? For example, if accessing the spreadsheet is taking more time than Foo and Goo, you won't get much benefit from the threading, and you'll certainly end up with more complicated code. (I think the Office COM objects are effectively single-threaded.) If Foo and Goo are the bottleneck, have you run a profiler on your existing code to see if you can make it faster without threading?
Do you have performance targets already? How close are you to meeting those targets? Don't bother trying to make the code as fast as it can possibly be, when you've already got it to run as fast as you need it to.
If Foo & Goo are not related, you could run them in two different threads making them run in parallel

Categories

Resources