8

I have a webapp written in C#, based on ASP.NET. It loads (with LoadLibraryEx) an unmanaged DLL written with C++Builder.

As I have performance issues I made some tests and comparisons, running always the same method in the DLL, for many times, obtaining average times.

I discovered that the DLL:

  1. loaded by a C++Builder console application, takes: 4.922 s
  2. loaded by a C# console application, takes: 5.484 s
  3. loaded by a minimal C# ASP.NET application hosted on IIS 7.5, takes: 9.551 s

As you see case 1 and 2 have very similar performance.

Why case 3 is so slow? Maybe IIS slows down the DLL?

For it I ran a profiling with JetBrains dotTrace: enter image description here

Is there any suggested IIS tuning?

Is there any suggested fast alternative to IIS for hosting ASP.NET webapps?

Should I consider porting the webapp to C++Builder?

EDIT:

I tried to migrate my webapp to ASP.NET Core (instead of .NET Framework) and run it on Kestrel. It takes 6.042 seconds. So, not so much overhead compared to the console app. It seems that IIS is the culprit... why?

bluish
  • 26,356
  • 27
  • 122
  • 180
  • What runtime(s) are you running the 2 C# applications in? Are they in release or debug when you're doing your tests? Are you testing just the function call or the application startup as well? – Blindy Jul 17 '20 at 15:41
  • @Blindy, by runtime you mean .NET Framework? Well .NET 4. I built always in Release mode. I tested just the function call. – bluish Jul 17 '20 at 15:44
  • Are you certain it's .Net 4 for both of them? Because that's a truly ancient runtime, you're at least 3 full releases of Net Core behind, Net 5, and the more modern Net Framework 4.6+. – Blindy Jul 17 '20 at 15:46
  • @Blindy I checked: both web and console applications have .NET Framework 4.7.2 as target framework in project properties. – bluish Jul 17 '20 at 16:11
  • So it is the ancient ASP.NET. Okay, what about the IIS hosting, is it out-of-process (classic) or integrated? Do you have a properly set up application pool for this? Is it dedicated to just your application or is it a shared pool? – Blindy Jul 17 '20 at 16:19
  • @Blindy, managedPipelineMode is Integrated. Yes, I have a dedicated application pool for this webapp. It is set with 32-bit enabled (DLL is built in 32-bit). – bluish Jul 17 '20 at 16:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/218044/discussion-between-bluish-and-blindy). – bluish Jul 17 '20 at 16:40
  • You can enable failed request tracing in IIS to trace the whole process. Then we can get which process take the longest time. If that issue haapened in managedpipeline. Then you can capture a dump snapshot. It will tell you which thread is running all the time and what the thread was doing. Then you should be able to find the root cause. – Jokies Ding Jul 20 '20 at 07:22
  • There's no reason why it should be twice the time. You can use a tool such as procmon from sysinternals to check what's loaded and timings when running in IIS vs other. One major difference is security context in general – Simon Mourier Jul 21 '20 at 16:06
  • @SimonMourier Thanks. I'm trying to understand ProcMon data, but I can't understand where to look, there are so many data (about registry, file system, network, threads, profiling events...) and I don't know how to use them. – bluish Jul 22 '20 at 07:00
  • Filter by the process name (usually w3something or wwwsomething.exe for IIS I don't remember), and start with files only (not register, etc.). You should now see what files are searched and where they are searched. And compare results "visually" between IIS and others. Procmon has timing info (or delta) – Simon Mourier Jul 22 '20 at 09:29
  • Just out of curiosity, are those figures in seconds? Like, 4 seconds, 5 seconds and 9 seconds in each instance? If yes, then I would forget about hosting app and probably investigate this library in detail to find out exactly what it is doing. In my programming life I havent seen a library that takes more than a few milliseconds to load. Anything above a second should be a problem in production. – Amogh Sarpotdar Jul 23 '20 at 09:44
  • I would recommend running profiler on your hosting app + library. I prefer Jetbrains dottrace but there are many more, including free alternatives. Look here - https://stackoverflow.com/questions/3927/what-are-some-good-net-profilers – Amogh Sarpotdar Jul 23 '20 at 09:47
  • Are you running an antivirus in the IIS host? If so, disable and test again. If the performance improves, make an exception on the AV to not scan that folder. – Jonathan Monestel Jul 24 '20 at 00:10
  • @AmoghSarpotdar thanks, I ran the profiler and posted the result in my question above... it confirms that IIS slows down the execution of the DLL, but we don't know in which particular DLL methods. About the bad performance of this library: for now we have to accept it :) Anyway this test considers the worst case. – bluish Jul 24 '20 at 06:57
  • @JonathanMonestel Thanks, but there is no antivirus. – bluish Jul 24 '20 at 06:57
  • @bluish : When diagnosing performance issues there are so many variables you have to consider, most important is the behaviour of the SUT. If this particular library is slow under IIS, it must be doing some operations which must be inherently slow under IIS's environment. For example, attempting to access some network share etc. Unfortunately in this case it looks difficult to do even 'guesswork' since we do not know anything about the culprit module. Btw, are those values in seconds? If yes, then its worth diagnosing the issue now rather than after a big blow up. – Amogh Sarpotdar Jul 24 '20 at 07:39
  • @AmoghSarpotdar yes, they are in seconds... this DLL does a big processing, so it is normal that it takes a long time. Anyway we are working on it. But in this question I'm investigating why IIS doubles the time of execution. Solving it we will have a big performance improvement! – bluish Jul 24 '20 at 07:59
  • @AmoghSarpotdar See also my EDIT on the question, please. – bluish Jul 24 '20 at 08:06
  • @bluish - [..continued] If using debug version, it will help if you copy pdb files of the dependencies of your application. Your profiler will be able to get inside the unmanaged code and record timings of individual function calls. Do you have access to the target binary? If yes, can you modify its code (startup functions) and put some TRACE statements in it? There is a tool called 'DebugView' published by SysInternals.com (again John Robbins), its free utility and allows you to view the trace calls in your library. – Amogh Sarpotdar Jul 24 '20 at 09:41
  • @bluish [...continued] You can find more about debugview here - https://learn.microsoft.com/en-us/sysinternals/downloads/debugview . This will be slow and painstaking work though, but you have little choice given the scenario. I would suggest placing TRACE statements in execution path, probably in startup functions of your binary. Then study the timeline to understand which part of code is taking longer time in execution. Finally, are you isolating the application in separate processing pool when monitoring the performance? – Amogh Sarpotdar Jul 24 '20 at 09:44
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/218521/discussion-between-bluish-and-amogh-sarpotdar). – bluish Jul 24 '20 at 12:58
  • Troubleshooting IIS Performance Issues or Application Errors using LogParser. https://learn.microsoft.com/en-us/iis/troubleshoot/performance-issues/troubleshooting-iis-performance-issues-or-application-errors-using-logparser – Nadeem Taj Jul 26 '20 at 11:37

1 Answers1

0

One cause that may explain your results is that IIS does not (by default) load your web app until the first time it is accessed. This can cause it to take longer as it will spin up the entire app after you navigate to the site whereas a console app will load the library as soon as the class that calls it is loaded into memory.

Eric
  • 464
  • 3
  • 7
  • Thanks Eric, but I measure the time just for the method that I'm testing. DLL is loaded and initialized long before. – bluish Jul 27 '20 at 06:33