Comment by jiggawatts

3 years ago

When they refreshed the Calculator app in the same way as Notepad, I went on a bit of a rant and "took it apart" with tracing tools to see where the computer power was going.

The problem is that modern package management tends to "drag in" unnecessary dependencies, each of which has to be loaded, remapped, virus-scanned, CRC-checked, etc...

The new Calculator was loading NVIDIA libraries, Windows Hello 4 Business Password Recovery helpers, and a decent chunk of a web browser.

Why?

1. Calculator gained some basic graphing capabilities, so it calls some DirectX functions, which call NVIDIA functions, which... drag in hundreds of megabytes of game driver garbage, including Event Tracing for Windows (ETW) circular logs that NVIDIA uses to spy on you. Err.. I mean "improve software quality".

2. It uses web requests (e.g.: currency conversions), which might need to go through a corporate proxy, which might need authentication, which might need Windows H4B, which might need a self-service password reset.

3. The aforementioned web requests use HTTPS and HTTP/3, which then drags in QUIC, a bunch of cryptographic libraries, CRL checking, Enterprise PKI policy, etc...

The hiccup is that all of this "work" is being done by the Calculator app itself, not the operating system. The OS just provides the DLL files, it doesn't pre-cache them in any meaningful way any more. These are all user-mode libraries, so each application has to load and process them in full.

Even in web development, you get the same effect. A small web site in ASP.NET / C# might have been 500 KB in the past and would load in milliseconds and then take 50 MB of memory. Now? If you add the new "session state" plugin, it drags in Azure SQL support, which needs Azure Active Directory Authentication, which needs OAuth, which needs JWT, which needs a JSON parser, which needs the new UTF8 decoders, which needs the new Memory/Span code, etc... That 500 KB app instantly bloats to 350 MB and takes 10 seconds to restart!

In NT4 and 2000 authentication and web proxies were "ambient" services provided by the OS, and much of it was in the kernel or pre-loaded and shared by all applications.

Summary:

The transitive dependencies of user-mode libraries are always processed in full. There's no compile-time "trimming" at this level. There's no try dynamic loading any more either, "dynamic" libraries are loaded statically because of hash-verification and anti-malware checks. There's no sharing any more to avoid DLL hell. All of the above also breaks the older optimisations where code was paged in dynamically.

The result is that it is "so easy" to write code now, but impossible to make it launch fast.