Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For a reason that is largely irrelevant, I installed Delphi 7 once again in such a long time. I have to say, I was completely blown away - in a way I haven't been for rather a while. This is not how I remember things at all. The installation took around 30 seconds. Launching it took 2 seconds, and it was immediately usable. I can press "Run" the second after it started, and less than a second later the blank program is already visible and running. Hurray for computers getting so much faster!

But the reason I've been blown away like this is because usually I use Visual Studio 2010, that doesn't feel snappy like this at all. Granted, Delphi 7 is a much smaller system than Visual Studio 2010, but it does have the appearance of having all the really necessary things there: a control palette, a form designer, a code editor with code completion. I realise that the language might be simpler, and the code completion might be a lot less powerful, and the IDE might not be nearly as extensible and feature-rich, but still: I do not understand how (i.e. through what mechanism) does having a lot of extra features (that I might not have even triggered yet) cause a system like Visual Studio to always feel sluggish in comparison.

I would like to ask people experienced in working with systems the scale of Visual Studio: what is it that makes them slow? Is it the layers upon layers of abstractions required to keep the codebase within the human comprehension capabilities? Is it the sheer amount of code that needs to be run through? Is it the modern tendency towards programmer-time-saving approaches at the (mindbogglingly huge) expense in the clock cycles / memory usage department?

share|improve this question

closed as too broad by gnat, Ixrec, Scant Roger, Bart van Ingen Schenau, GlenH7 Jan 6 at 18:53

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

7  
Simple: as mass increases, more force is required to overcome inertia. – Shog9 Jan 22 '11 at 3:57
    
Someone once told me managers but I don't believe that at all. – MIchael Grassman Jan 22 '11 at 4:16
1  
This is a large part of the reason I still primarily use D7 for Delphi programming. – GrandmasterB Jan 22 '11 at 6:31
    
The fastest code is that which never gets executed. – Henry Jan 24 '11 at 0:06
4  
@romkyns: I find much software in the modern era is often incredibly bloated, unnecessarily large and unwieldy. A lot of the software now solves the same issues that were solved ten, even twenty years ago, with a fraction of the power and space. Why does it still lag as badly as it ever did, if not more so? Inefficiency and bloat. – Orbling Jan 24 '11 at 0:48
up vote 19 down vote accepted

Architectural Astronautics

Visual Studio 2010 is built upon Windows Presentation Foundation. Take a look at the Button class for WPF. It is the 9th child of a base class. It has around 5 pages of properties, methods, and events. Behind the scenes it has another five pages of style definitions that describe its beautifully rounded corners and the subtle animation transitions when a mouse cursor moves over it. This is all for something that fundamentally displays some text or a picture and produces a click event when it detects a mouse button going down.

Stop a program like Visual Studio at any random point. Look at the stack trace. Chances are very good that you're 20 levels deep into the calling stack and that five DLLs were loaded to get there.

Now, compare these two things with Delphi. I bet you find that a Delphi Button has just 20 properties, methods, and events. I bet the Delphi IDE only has a stack trace 5-7 levels deep. Because when computers were slower, you just couldn't take the overhead of Visual Studio 2010 without the IDE taking 40 minutes to start :-)

Is one better than the other? Well, I can generally tell a Delphi program when it loads because it looks flat, the colors are muted (8 bit perhaps?), and there's no subtle shading or animation. I just feels 'cheap' these days. Cheap, but fast.

Are we better off? That's a question for the philosophers, not the coders.

share|improve this answer
3  
A delphi program doesnt look flat. Rather, a programmer programs a program to look flat. You can make nice looking, modern, full color interfaces with Delphi just as you could in C# or C++. – GrandmasterB Jan 22 '11 at 6:35
2  
This is an insightful answer; but I’m not sure it is complete. Visual Studio 2008 (the predecessor of 2010) has no WPF in it and is still worlds slower than Delphi 7. Would you still say the same thing about the call stack depth and the number of DLLs loaded? – Timwi Jan 22 '11 at 14:14
3  
@Timwi Yes, absolutely I would. My point was less about the evils of WPF (I like WPF actually) and more about how we tend to add layers upon layers of software abstraction when given the choice. Perhaps Visual Studio 2008 didn't have quite as much overhead, but as you noted it had quite enough :-) – Jay Beavers Jan 22 '11 at 21:10
    
@GrandmasterB, I'm not slamming Delphi because it comes with fewer assumptions and simpler libraries. WPF was designed assuming GPU hardware acceleration would allow programs to use deeper colors, frequent animations, alpha blending, shadows, etc. Delphi was engineered at a time when these assumptions could not be made. Could you re-implement this all in Delphi? Sure, but you'd have to put a lot of coding in just to get the behavior of a WPF button. On the plus side, a Delphi button doesn't come with CPU, memory, and GPU requirements a WPF button has either which was the @OP's question. – Jay Beavers Jan 22 '11 at 21:13
7  
Your argument for flat and plain UI is completely invalidated by Windows 10's new 'Modern' UI. Now we have all that overhead in order to create flat, square, plain buttons like we had 30 years ago. – gbjbaanb Jan 5 at 14:58

I would like to ask people experienced in working with systems the scale of Visual Studio: what is it that makes them slow? Is it the layers upon layers of abstractions required to keep the codebase within the human comprehension capabilities? Is it the sheer amount of code that needs to be run through? Is it the modern tendency towards programmer-time-saving approaches at the (mindbogglingly huge) expense in the clock cycles / memory usage department?

I think you guessed a number of them but I would like to offer what I consider to be the biggest factor, having worked on a reasonably large codebase (not sure if it's as big as Visual Studio -- was in the millions of lines of code category and around a thousand plugins) for about 10 years and observing phenomena occur.

It's also a bit less controversial since it doesn't go into APIs or language features or anything like that. Those relate to "costs" which can spawn a debate rather than "spending", and I want to focus on "spending".

Loose Coordination and Legacy

What I observed is that loose coordination and a long legacy tends to lead to a lot of accumulated waste.

For example, I found around one hundred acceleration structures in this codebase, many of them redundant.

We'd have like a K-D tree for accelerating one physics engine, another for a new physics engine that was often running in parallel with the old one, we'd have dozens of implementations of octrees for various mesh algorithms, another K-D tree for rendering, picking, etc. etc. etc. These are all big, bulky tree structures used to accelerate searches. Each individual one can take hundreds of megabytes to gigabytes of memory for a very average-sized input. They weren't always instantiated and used all the time, but at any given time, 4 or 5 of them might be in memory simultaneously.

Now all of these were storing the exact same data to accelerate searches for them. You can imagine it as like the analogical old database which stores all of its fields into 20 different redundant maps/dictionaries/B+ trees at once, organized identically by the same keys, and searches all of them all the time. Now we're taking 20 times the memory and processing.

In addition, because of the redundancy, there's little time to optimize any one of them with the maintenance price tag that comes with that, and even if we did, it would only have 5% of the effect it ideally would.

What causes this phenomena? Loose coordination was the number one cause I saw. A lot of team members often work in their isolated ecosystems, developing or using third party data structures, but not using the same structures other team members were using even if they were outright blatant duplicates of the exact same concerns.

What causes this phenomena to persist? Legacy and compatibility was the number one cause I saw. Since we already paid the cost to implement these data structures and large amounts of code were dependent on these solutions, it was often too risky to try to consolidate them to fewer data structures. Even though many of these data structures were highly redundant conceptually, they weren't always anywhere close to identical in their interface designs. So replacing them would have been a big, risky change as opposed to just letting them consume memory and processing time.

Memory Efficiency

Typically memory use and speed tend to be related at the bulk level at least. You can often spot slow software by how it's hogging up memory. It's not always true that more memory leads to a slowdown, since what matters is "hot" memory (what memory is being accessed all the time -- if a program uses a boatload of memory but only 1 megabyte of it is being used all the time, then it's not such a big deal speed-wise).

So you can spot the potential hogs based on memory usage a lot of the time. If an application takes tens to hundreds of megabytes of memory on startup, it's probably not going to be very efficient. Tens of megabytes might seem small when we have gigabytes of DRAM these days, but the largest and slowest CPU caches are still in the measly megabytes range, and the fastest are still in the kilobytes range. As a result, a program that uses 20 megabytes just to start up and do nothing is actually still using quite "a lot" of memory from the hardware CPU cache point of view, especially if all 20 megabytes of that memory will be accessed repeatedly and frequently as the program is running.

Solution

To me the solution is to seek more coordinated, smaller teams to build products, ones who can kind of keep track of their "spending" and avoid "purchasing" the same items over and over and over.

Cost

I'll dip into the more controversial "cost" side just a teeny bit with a "spending" phenomena I've observed. If a language ends up coming with an inevitable price tag for an object (like one that provides runtime reflection and cannot force contiguous allocation for a series of objects), that price tag is only expensive in the context of a very granular element, like a single Pixel or Boolean.

Yet I see a lot of source code for programs which do handle a heavy load (ex: dealing with hundreds of thousands to millions of Pixel or Boolean instances) paying that cost at such a granular level.

Object-oriented programming can kind of exacerbate that. Yet it's not the cost of "objects" per se or even OOP at fault, it's simply that such costs are being paid at such a granular level of a teeny element that's going to be instantiated by the millions.

So that's the other "cost" and "spending" phenomena I'm observing. The cost is pennies, but pennies add up if we're purchasing a million cans of soda individually instead of negotiating with a manufacturer for a bulk purchase.

The solution here to me is "bulk" purchase. Objects are perfectly fine even in languages that have some price tag of pennies to each one provided that this cost is not being paid individually a million times over for the analogical equivalent of a soda can.

Premature Optimization

I never quite liked the wording Knuth used here, because "premature optimization" rarely makes real-world production programs go faster. Some interpret that as "optimizing early" when Knuth meant more like "optimizing without the proper knowledge/experience to know its true impact on the software." If anything, the practical effect of true premature optimization is often going to make software slower, since the degradation in maintainability means there's little time to optimize the critical paths that really matter.

This is the final phenomena I observed, where developers reaching to save pennies on the purchase of a single can of soda, never again to be bought, or worse, a house, were wasting all their time pinching pennies (or worse, imaginary pennies from failing to understand their compiler or the architecture of the hardware) when there were billions of dollars being wastefully spent elsewhere.

Time is very finite so trying to optimize absolutes without having the proper contextual information is often depriving us the opportunity to optimize the places that genuinely matter, and thus, in terms of practical effect, I would say that "premature optimization makes software much slower."

The problem is that there are developer types who will take what I wrote above about objects and try to establish a coding standard that bans object-oriented programming or something crazy of that sort. Effective optimization is effective prioritization, and it's absolutely worthless if we're drowning in a sea of maintenance problems.

share|improve this answer
2  
Technical debt, in other words. Technical debt that is never paid off. – Robert Harvey Jan 5 at 15:02
1  
Robert is correct. One mistake from a guy, two hundred mistakes --forced by managers yelling "you'll be fired if you don't implement this by tomorrow" that blow away years of good software engineering practices, TDD, unit testing and any human and sane programming principle, plus two other times you were tired.. that guy who left the company mad because he was laid off for no reason and messed up the codebase.. those discontinued libraries you never updated... and here you have it: delicious spaghetti codebase and bloated software. Bon appetit – user3834459 Jan 5 at 15:11
2  
Interesting, especially in how you've seen excessive granularity misused. I have caught myself doing something similar on occasion in the past and got poor performance as the result. This is quite similar to your answer from a few days ago about using collections and bulk algorithms in preference over excessive granularity. I cannot believe that answer was not more appreciated for its profundity. It makes me rethink several of the designs that I have built over the years. I wonder why those techniques are not more widely promoted? – Mike Jan 5 at 15:49
2  
@Mike I'm a bit of a broken record when it comes to trying to promote more of a data-oriented mindset. It is popular in the gaming industry where they're trying to utilize every inch of the hardware. That said, it does admittedly reduce flexibility. If you have an abstract pixel class, you can do crazy things with that like have a single image that mixes two or more different pixel formats! Yet when we're dealing with critical paths, probably no image would benefit from that level of flexibility, and performance starts to become a real concern with anything involving images and pixels. – Ike Jan 5 at 16:10
1  
In the bad old days I implemented some code to bypass the graphics APIs and directly access pixels in memory for a critical piece of my code. The difference between the many layers of abstraction and direct access was something like 100x, which mattered on a computer in those days. Now you computers are fast enough that you can slog through any amount of abstraction, if you have to. – Michael Shopsin Jan 5 at 16:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.