Clean Design vs Efficiency

Started by
15 comments, last by Emmanuel Deloget 13 years, 2 months ago

I get a feeling that the people who voted for "efficiency" have not worked in a corporate setting for long, or at all.
My experience from corporate settings is that "clean design" means "over-engineered and bloated" ;)
If a design is clean, it will be easy to change large scale factors that would make it efficient later.If the "clean design" itself is the reason for the inefficiency though, then the "large scale factors" that need to be changed are the design itself.... which means that you've written a prototype that needs to be rewritten properly.
Developing poor code adds a lot of time when something large scale wants to get changed, and in the end may doom a project."Clean" design can potentially lead to poor code though.
In my earlier example, you start out with a fairly simple object model. Translating this model over to OO code creates a "clean" implementation, but is absolutely horrible in terms of the CPU's strengths/weaknesses. The re-implementation of the code, which no longer looks like the original "clean" model, is actually implemented with the target platform in mind, and accordingly performs much better.
Develop a clean design and you will have, by nature, developed an efficient one as well.It's great to have a nice clean model designed, but these abstract models don't get executed by some particular machine - code does. In order to design an efficient model (regardless of cleanliness), the model has to take into account the hardware on which it's going to be implemented. No matter how clean the design is, if it disregards the target hardware, then it's bound to end up being quite inefficient in ways that no large scale reorganisation of the design can address.
Advertisement

'scwizzo' said:

I get a feeling that the people who voted for "efficiency" have not worked in a corporate setting for long, or at all.
My experience from corporate settings is that "clean design" means "over-engineered and bloated" ;)

I would say that clean design is by definition not over-engineered and not bloated. It fits the purpose, nothing more, nothing less. If it does more, then someone lost its time doing it. If it does less, then someone is not doing its job properly. But I agree that many people tend to think their architecture is well executed while it's not the case.


If a design is clean, it will be easy to change large scale factors that would make it efficient later.
If the "clean design" itself is the reason for the inefficiency though, then the "large scale factors" that need to be changed are the design itself.... which means that you've written a prototype that needs to be rewritten properly.
It seems you have an issue with architects :)


Developing poor code adds a lot of time when something large scale wants to get changed, and in the end may doom a project.
"Clean" design can potentially lead to poor code though.
By definition, no. Poor design lead to poor code.

In my earlier example, you start out with a fairly simple object model. Translating this model over to OO code creates a "clean" implementation, but is absolutely horrible in terms of the CPU's strengths/weaknesses.

No, the implementation s hideous, and does not respect at least one basic principle of OOP : the Liskov Substitition Principle. Foo and Bar might be world objects, but their behavior is completely differrent. If there is a need for polymorphism, then it shall not be dynamic in this case - but one can always resort to parametric polymorphism (i.e. use templates, which can too trash the cache). (BTW, using shared pointer is a failure by itself :) either you know who owns the objects, or you don't know that and you're screwed, whatever you do to avoid taking the responsibility of trying to clearly define object ownership).


The re-implementation of the code, which no longer looks like the original "clean" model, is actually implemented with the target platform in mind, and accordingly performs much better.

It is also far superior in terms of design. OOP doesn't mean that you have to put everything into objects - that doesn't make much sense : is cos(x) an object ?


Develop a clean design and you will have, by nature, developed an efficient one as well.

It's great to have a nice clean model designed, but these abstract models don't get executed by some particular machine - code does. In order to design an efficient model (regardless of cleanliness), the model has to take into account the hardware on which it's going to be implemented. No matter how clean the design is, if it disregards the target hardware, then it's bound to end up being quite inefficient in ways that no large scale reorganisation of the design can address.

Not only it should take the HW into account, but it also need to take the compiler into account ; different compilers do things differently, and a clean design shall be able to allow for compiler-specific optimization when they are needed (this can be done cleanly in C++ using, again, parametric polymorphism ; the classical way to do this is to use compile time policies).
I think a clean design is something you should strive for first. Optimization is much more effectively done on cleanly designed code. And often times after you implement something you find that it will not need optimization.

I get a feeling that the people who voted for "efficiency" have not worked in a corporate setting for long, or at all. If a design is clean, as it's been said, it will be easy to change large scale factors that would make it efficient later. Developing poor code adds a lot of time when something large scale wants to get changed, and in the end may doom a project. Develop a clean design and you will have, by nature, developed an efficient one as well.


ditto
My first actual expert grade mentor once told me "If someone tells you a certain way of coding is more efficient, its normally just because s/he wants his/her way."
I get a feeling that the people who voted for "efficiency" have not worked in a corporate setting for long, or at all. If a design is clean, as it's been said, it will be easy to change large scale factors that would make it efficient later. Developing poor code adds a lot of time when something large scale wants to get changed, and in the end may doom a project. Develop a clean design and you will have, by nature, developed an efficient one as well.

You can't really apply principles suitable for a corporate setting to games (which is what the OP asked about); it's comparing apples to oranges. Well, you can, but you should be aware of what you're doing and why you're doing it, and reasonably certain that you're going to get definite ROI from it.

Having said that, clean design wins every time. Unless you seriously overengineer the thing, with multiple layers of abstraction, the performance trade-off (assuming that there even is one) should be minimal. Then profile, identify your bottlenecks, and tackle them explicitly.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


[quote name='scwizzo' timestamp='1294941993' post='4758383']I get a feeling that the people who voted for "efficiency" have not worked in a corporate setting for long, or at all. If a design is clean, as it's been said, it will be easy to change large scale factors that would make it efficient later. Developing poor code adds a lot of time when something large scale wants to get changed, and in the end may doom a project. Develop a clean design and you will have, by nature, developed an efficient one as well.

You can't really apply principles suitable for a corporate setting to games (which is what the OP asked about); it's comparing apples to oranges. Well, you can, but you should be aware of what you're doing and why you're doing it, and reasonably certain that you're going to get definite ROI from it.
[/quote]
This is kind of weird to me. Corporate settings are defined to

1/ make sure ROI is here
2/ ensure software quality

Which are desirable properties, even in the game development world.

I agree that in many situations, large corporations tends to implement policies that go too far beyond these goals, mostly because they have to deal with existing softwares or software with a very long life cycle (defense contract in France requires companies to provision development time for 10 to 30 years), because in some situations development teams can be quite large (how many people are working on the next iteration of Windows? Think to a digit in the 2-5 range, multiply by 1000, and you'll get a number which is not very far from the reality) and because (sorry for non game development companies(*)) they also have to deal with a non-null pool of inneficient developers. This is a Bad Thing, true.

But then:

1/ game code base tend to have a life cycle which is longer and longer (see third party and in-house middlewares)
2/ teams are increasingly large (see the credits for TES:Arena, then TES:Daggerfall, then TES:Morrowind, then TES:Oblivion)
3/ in these teams, it is inevitable that the developers efficiency level are disparate.

The game industry is facing the same evolution than the classical software industry, and one of its challenge is to handle this evolution cleanly. More and more software engineers are recruited (10 years back, providing a convincing demo of your skills was enough to get a job in the GI), and game development companies now implement helpers that have been common in the software industry for the past 5 to 10 years (continuous integration, source version tracking, bug tracking, but also architecture documents, multi-team setup and so on).

So in essence, comparing the classical software industry and the game industry is not the same as comparing apples to oranges : it's comparing an old, solid, calm apple tree to a young, shiny and vigorous apple tree. The young tree learnt from the experience of the old tree and try to not reproduce the same errors, with various results (read the various post mortem in GDmag, and see how many of them cite development problems due to a code base that grew out of control).


Having said that, clean design wins every time. Unless you seriously overengineer the thing, with multiple layers of abstraction, the performance trade-off (assuming that there even is one) should be minimal. Then profile, identify your bottlenecks, and tackle them explicitly.


That + code for your platform, know your build settings (including your compiler) and so on. All the things an architect should master before he can call himself a software architect. Vitruvius already saw this point 2000 years ago: you cannot be an architect if you don't know at least a large part of everything which is important in your industry. You have to have a clear understanding of both the theory (architecture principles ...), the history of your engineering field and the practice (implementation). Missing one of these will either lead you to inneficient architecture, reproduction of common errors, unscalable conception, and so on.

[size="1"](*) disclaimer: I do not work in the game industry (I work in the telecom industry ; I spent most of my work life on embedded, critical systems). I worked in the game industry, and I have continuously studied it for the past 15 years.

This topic is closed to new replies.

Advertisement