RE: [GD-General] Compile times
Brought to you by:
vexxed72
|
From: Brian H. <bri...@py...> - 2002-12-09 21:34:38
|
> I'm totally impressed. When you say complete build times, that means
> *all* the code involved in Quake 2 or Quake 3? All the DLLs,
> everything? Was there some trick you were using to get such
> incredible build times (other than using straight C)?
If I remember correctly, yes.
Okay, Quake 2 is open sourced, so I just tested it out. On my very
modest 2xP3/933 w/ 512MB RAM using MSVC 6, compiling ref_gl, game, and
client, it took 37 seconds.
Let me repeat: 37 seconds.
Compiling each component averages 10-15 seconds for a full rebuild. If
editing a single source file, compile-edit-run is probably 3 seconds.
The trick was careful engineering. Nothing mind boggling, just doing
the obvious stuff. <windows.h> was limited to only the files that
needed it. We used ANSI C, not straight C++. But even so, if you don't
use templates heavily or STL, straight C++ can compile very quickly as
well. Dependencies between modules were well guarded -- changes to the
renderer data structures had no effect on the game source code. Changes
to the network stuff had no effect on the renderer, etc.
There was absolutely nothing magical about it, and that's why I'm
honestly confused and addled by the seeming necessity today to spend 10+
minutes to rebuild games on top notch hardware. And most new games
today use scripting languages, so the build times should be close to
non-existent (Q2 had no scripting language).
Quake 3 was not significantly more complex, unless the Q3VM stuff that
John did ended up taking a lot of time, but I highly doubt that as well.
> We're using C++ and STL, and even though we have a good
> physical organization (like Lakos described), compiling all
> our libraries and game code for one platform could take up to
> 15-20 minutes. That's only for a full build; a quick change
> somewhere still requires building that file and then doing a
> link, which is about 30-40 seconds.
>
> I find 30-40 seconds for a trivial change close to
> unbearable. Especially when it takes another 10 seconds for
> the game to start and another 10 seconds for the level to load.
The above is exactly what I mean. STL is the devil's tool, I stand very
firmly on that. I completely dislike the way C++ has made templates,
which are effectively glorified search and replace macros. It leads to
code bloat, and changing any of your template code causes massive
cascades of rebuilds.
> What are other people doing to reduce their compile times?
> Getting rid of STL is not really an option. It's way too
> useful to replace it with a crippled, custom
> container/algorithm set that is probably not even type safe.
I just don't buy this one second. We survived and thrived just fine
before STL. STL is very, very convenient, but is it worth that cost? I
don't think so, not one bit.
Writing basic data structures like sets, lists, hashes, etc. is stuff we
all did as undergrads in college. In the massive, grand scheme of
engineering, it's a non-issue. It's tedious, sure, but even then, that
tedium is measured in minutes or hours, not days and weeks. The
overhead from using STL or any other features that incur extensive build
times affects you through the life of the project. Every compile.
This, to me, is one of the biggest indicators that software engineering
has gotten completely out of hand. And I'm not coming down on you
specifically, because pretty much 90% of all game companies that I'm
aware of are using STL or something similar in such a capacity, and
incurring the costs. Yet I rarely see any potential benefits measured
concretely by this.
Probably the #1 defense for STL is that it prevents you from doing
something lame just to get things going. The classic case is, say,
hardcoding an array when you should have a proper container class. Or
using a linear search when a proper set/bag/map should be used. But 20
minutes per rebuild (and in many cases, much much more from what I've
heard) to make up for lack of programmer discipline seems ridiculous.
I use linear searches. And when I know they're going to be a problem, I
substitute something better. I usually put in a comment like:
//fixme: don't do a linear search here!
But it lets me get something implemented, and then I can substitute it
later on demand.
This isn't a case of NIH, which is the common counterargument when I
rant about STL. I'm 100% for code reuse, and in fact use a ton of open
source libraries in my own code -- Lua, libpng, ijg, ogg vorbis, SDL,
etc. But when code reuse has a measureable cost on productivity without
an associated benefit, I have to raise an eyebrow.
I just remain 100% unconvinced that STL (or almost any library or
language feature) is worth the loss of hours each day in build times.
Anyway, enough lecturing on that =)
The only other things you can do is go through with heavily analyze
every single dependency you have and try to minimize them. A common
enough thing is to revert to pure dynamic allocation so that changing
the physical structure of a class won't force rebuilds by clients of
that class, i.e. the classic:
//publicly export this
class FooInterface
{
public:
virtual void interfaceFunc( void ) = 0;
};
//only seen by the Foo module
class FooImplementation : public FooInterface
{
...
};
This can hurt though, since I personally abhor excessive dynamic memory
allocation. I much prefer to have my data structures pre-allocated as
much as possible, even though this does cause a much greater dependency.
-Hook
|