Raised This Month: $51 Target: $400
 12% 

STL versus CUtl?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
theqizmo
Member
Join Date: Oct 2004
Old 04-06-2005 , 16:26   STL versus CUtl?
Reply With Quote #1

Quote:
Originally Posted by http://www.sourcewiki.org/wiki/index.php/Technical_FAQ
Is there a particular advantage to generic utility classes like CUtlVector or can i just use the standard template library?
For those of you who aren't familiar with the Standard Template Library (http://www.sgi.com/tech/stl/), it's a set of very useful data structures and algorithms provided by most development environments. However, a lot of the data structures in it aren't needed for HL2, and the ones that are useful can probably be optimized for HL2-specific use. So Valve has implemented their own common set of data structures, the CUtl* classes. Most of these are going to be more efficient than their more-general STL counterpart. Also, they're already compiled into HL2, so using them won't increase your code size at all. However, to take advantage of the STL, you'd would need to include all of the relevant code - and the STL is comparatively large. So, in short, use CUtl* classes over STL classes if at all possible. If you can't live without an STL class, see if you can build it cheaply off of some CUtl* classes.
Unless performance is statistically greater in significant portions across every platform, I do not believe in the statement from this article.

A) Efficiency
It is not necessarily the same across every platform. ValvE uses optimizations in windows heavily, with some linux optimizations when they can find the time/resources.

STL has been created for efficiency across every platform, although there are optimizations that each library ( for the specific platform ) has made for its own platform.

In the context of HL2 modification programming, CUtl* may be more efficient with specific HL2 structures that were designed to work specifically with those, since it's the inherant design of the set of templates.

However, I wouldn't assume that it's more efficient just because ValvE wrote them. ValvE coders may have specialties, yet they must rely on their game programming expertise such that they have their jobs. On the other hand, the STL coders have been working on the code specifically for any structure of data.

B) Binary size bloating
I see this as a moot point. Go ahead and statically link your plugin/mod against STL. Your binary size may increase, but, with the cost of disk space decreasing, and with the possible tradeoff of increased performance/efficiency, it is a relatively nice gain.

C) Compatibility
Mattie made a good point in the other post with the problems with older versions of gcc and libstdc++. Sometimes STL may not be compatible with older versions of gcc, HOWEVER, HL2 plugins require 3.4.X, and thus, get your lazy self into gear and upgrade gcc/libstdc++ whenever it is possible.

This shouldn't be an issue with CUtl*, since ValvE had made sure that it was compatible across both platforms that they support (win32 and linux).

However, what if you want to use an algorithm in the industry, outside of HL2? You would have to completely rewrite it using STL, and that would be a waste of an important concept of C++: reusability.

D) STL just makes sense
I can't add much to this except the examples of push_back and pop, and this isn't certainly a strong argument.

Although I am not an assembly language guru, nor am I anywhere above intermediate, however, those terms specify push and pop as ways of manipulating data on the stack.

I don't see why CUtl* has to move away from this, as you push the data onto the container, then you pop it off. AddTo* and Remove makes more sense in plain English, and probably appeals to those without a background in lower level languages, however, I don't see the sense in renaming them to appeal to other programmers.

Just understanding what each function does should be enough to use it, yet if you don't have time to learn the accepted standard, then I guess you can use the nonstandard.


I will see if I can find someone who can run extensive testing to see how fast it is to use a CUtlVector versus std::vector of int, std::string, and some other structure that I'll have to lookup, but specifically a data structure that ValvE has created for HL2. Maybe they can test different versions of gcc/libstdc++ that has different algorithms for std::vector (if it has changed at all recently) as well.
I will definitely look into this so that I can support my claims, or concede them.


Please post constructive criticism, don't flame me if you find credible data that makes my point absolutely wrong. I'm not trying to attack anyone who loves the CUtl*, either, but rather, I would like to show those who don't know about STL to look into it as a possibility.
theqizmo is offline
Send a message via ICQ to theqizmo Send a message via AIM to theqizmo Send a message via MSN to theqizmo
Mattie
Veteran Member
Join Date: Jan 2005
Old 04-06-2005 , 17:28  
Reply With Quote #2

As we touched on in other threads, I think this probably just comes down to preference.

I strongly suspect (as you do) that performance won't be a big factor, especially in the areas where I toil, server plugins.

I tend to prefer working within an SDK whenever I code for an environment. I'm not a big fan of adding technologies to a project when I already have parallels available. As such, my personal recommendation is for developers to initially try to use the the classes made for use within an SDK (e.g. the Source SDK).

That being said, I have zero problem with developers using STL and other development technologies if they (a) need them and (b) understand the implications of including them.

If the Valve SDK doesn't provide what you need, don't bend over backwards to create it using Valve's structures. Just be aware that the ballgame changes slightly in your project whenever you take advantage of new libraries. E.g., you have to reformat data at times, you have to include and manage more header files, and you can inadvertantly increase your compile-time dependencies and (sometimes) run-time dependencies.

Your portability argument is fairly sound, but I'm not so sure it will come up a lot. Even still, most of the work of porting to a new game, etc, probably isn't in the generic classes/functions you use, but adapting to the new architecture. Vectors/stacks/queues, etc are common enough constructs that you can pretty much always count on having them available (or write your own).

Anyway, the bottom line for me is that it's probably just one of those coding preferences. My preference is to stay within the SDK when it's possible-- only dipping outside when I feel it's necessary. I can't say I'd be bothered if other developers felt differently.

-Mattie
Mattie is offline
vancelorgin
Senior Member
Join Date: Dec 2004
Location: san frandisco
Old 04-06-2005 , 22:35  
Reply With Quote #3

I understand both points of view in their own context, but I know and have seen the speed of [msvc's] stl at the asm level, and trust it more than any valve creation. Speed is not a moot point if your server plugin hooks every entity callback and some unholy number of other functions
__________________
Avoid like the plague.
vancelorgin is offline
theqizmo
Member
Join Date: Oct 2004
Old 04-06-2005 , 23:29  
Reply With Quote #4

I'm not saying, Mattie, that you are some evil Valve fan and that I will start a crusade to bring down your plugin, just because you use CUtlVector.

I understand that people would prefer not to use "extra" libraries, and only stick with what they have.

Performance is indeed not a big factor, however, performance is always a major issue in any program, and in this context, performance of these libraries is that it extends to what you are doing.

If you are using CUtlVector to manage hundreds/thousands of data sets, I'd seriously reconsider using std::vector.

However, if you only use CUtlVector to manage ints or bools, or maybe a set of data that is relatively the same (in terms of being added/deleted), such as self created player classes, it probably won't hurt performance in terms of using it.

However, just for coding consistency, I would definitely suggest using only one.

Mattie, there is only one thing with which I definitely don't agree (in parts, anyway):
Quote:
Originally Posted by Mattie
Just be aware that the ballgame changes slightly in your project whenever you take advantage of new libraries. E.g., you have to reformat data at times, you have to include and manage more header files, and you can inadvertantly increase your compile-time dependencies and (sometimes) run-time dependencies.
- HL2's CUtlVector is "newer" than STL, however, the generalization does work otherwise, but only if you don't know how to add a library to your project, use its headers, and link it against your program properly.

- I don't see where you get "reformat data" unless you mean how each template class is different in terms of usage, but yes, if you had an alternate form of templates, it would be "harder" to maintain in the sense that everywhere that the templates are used the files must be included, but then again, if you don't have the specific header, it won't compile.

- Managing more headers is a moot point since you have to make sure your headers are included properly for CUtlVector

- Compile-time dependencies should not matter, only the plugin author sees them.

- Run-time dependencies should not matter, as the increase in time for the plugin to load just because STL was added is so insignificant that I doubt any current, playable, HL2 server would notice the change. If you can document an increase in performance on a server that is capable of hosting a 12 player source server when any library that people would specifically link against publically versus when that library is not linked against, I would like to see. =x

*edit: note, that after the first sentence, I am talking in general, and not specifically to any person. added to run-time dependencies, etc,
theqizmo is offline
Send a message via ICQ to theqizmo Send a message via AIM to theqizmo Send a message via MSN to theqizmo
Mattie
Veteran Member
Join Date: Jan 2005
Old 04-07-2005 , 00:15  
Reply With Quote #5

Quote:
Originally Posted by theqizmo
- HL2's CUtlVector is "newer" than STL, however, the generalization does work otherwise, but only if you don't know how to add a library to your project, use its headers, and link it against your program properly.
Unfortunately, I'm not sure you see my point here. It's not a know-how thing, it's an increase-in-project-complexity thing. (Unfortunately I don't have time to clarify that point much tonight-- sorry if I was unclear.)

Quote:
- I don't see where you get "reformat data"
Here I mean conversion when you need other areas in the SDK that use/require data types from the Valve SDK. The most basic example is when a char* is required and you're playing around with 'string's. It's not a big concern, but something you just have to 'do' when you add in other classes to manage your data types. At some point, conversions usually have to be made.

Quote:
Managing more headers is a moot point since you have to make sure your headers are included properly for CUtlVector
As most of those comments/examples, this is more generic than specific. I mean "more headers" in cases where you already need to use Valve data types to interface with Valve API (i.e. you already include those headers) and then you add STL headers for similar classes. In the end, you have a few implementations of vector in your project. This is also entirely a minor thing. (I can see where my preference here stems partly from projects I've worked on with lots of maintainers who will come in and can't easily tell which of the similar classes are the project's preference.)

Quote:
Compile-time dependencies should not matter, only the plugin author sees them.
This remark bothers me a tad, but not enough to sidetrack the discussion much. There're lots of times where adding compile-time dependencies is not a trivial matter. Perhaps I'm just risk-averse due to developing on so much shrink-wrapped software, but I don't take increasing the build requirements lightly. For plugins and mods, you're almost certainly right-- this is probably not important enough to cause someone to shy away from something. Yet, for any large project this isn't something you'd do when you didn't need to do so. So it gets an automatic hesitancy factor when I consider it.

Quote:
Run-time dependencies should not matter, as the increase in time for the plugin to load just because STL was added is so insignificant that I doubt any current, playable, HL2 server would notice the change.
This isn't a performance issue but a project complexity issue. I was speaking in general here about other libraries and not specifically about STL, since you shouldn't have much run-time affect if you link statically against the STL.

In short, I don't disagree with your points, especially when viewed from the perspective of typical plugin development. This doesn't alter my preference, though. I'd prefer to stay within an SDK than to delve outside until it was beneficial to do so (e.g. when I run into reinvent-the-wheel or performance issues with what I have).

Thanks for the discussion,
-Mattie
Mattie is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 10:08.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode