Using 3rd party libraries or code your own?

Started by
21 comments, last by Kian 9 years, 9 months ago

So I was looking through the Unreal 4 source and I see that they have everything as you would imagine, a whole string library pretty much the same as Boost. Now I guess they are so used to always writing their own as libraries as libs like boost haven't been around for long but I am guessing they could knock maybe up to a third of their code off from using libs like Boost, and various other highly optimised libs.

So what are your thoughts here, write your own or use third party?

Advertisement
It's going to depend.

For my own personal projects I tend to write my own because I enjoy learning new things by writing "from scratch" as it were. Though for things I've already written before and/or understand I'll use a library (i.e. C++ STL library) to save time. In these cases execution speed isn't a huge deal because I'm not writing huge AAA games with the latest tech at home.

Professionally it's also going to be a mix. You'll find a lot of companies using middleware like Havok or Unreal, texture loaders like DirectXTex, XML parsing libraries, etc. Not aware of many using boost - it tends to very quickly bloat compilation times and has the same problem STL has in that it's optimized for the general case.

There is, however, a bit of a stigma against the C++ STL library due to studios being burned by badly written implementations in the past - and in some cases, companies will write their own implementation of things like arrays or strings because they can actually write them faster or more memory efficient then the "standard" version for their particular use case.

A good example is the strings you brought up. A common thing to do is to write a string class that stores string data in a large table, and then if someone makes another string with the same data it points at the table instead of allocating more memory. Not only does this save on memory over the STL implementation (which has to allocate memory for every string copy), but you can get lightning-fast string comparisons because you only have to compare pointers and not whole strings. The downside is that these kinds of strings are immutable - but for a game, that is rarely a problem.

Edit: Most of the above should probably be prefixed with "In my experience" - though that may be assumed tongue.png


a whole string library pretty much the same as Boost.

When it comes to the C++ standard library, and also tasks like string manipulation, there is a lot of subtlety involved beyond just the public-facing API.

Carefully read this report given to the C++ standards committee. You will probably find it enlightening, as it describes many of the tiny reasons the standard library doesn't precisely fit our industry's needs. Some of the reasons are common, even after 20 years there is no really good solution to the problem of allocators inside template collections as they relate to code boundaries. Others are less common, like the desire to bulk-destruct objects without calling their destructors.

The decision to use a third party library is never an easy one.

I personally don't believe in re-inventing the wheel, if someone has already done a really good job of doing something, why should I invest the time doing the same ?

However there are times when "the best out there" isn't good enough. Then you need to get involved and do some serious coding.

It's a cost versus advantage equation.

If using an external library saves you 3 man months of coding at the cost of 1ms per loop, it's probably an easy decision ... until you really need that millisecond smile.png

We use third party code, and pay a lot for the privilege. It's not always a good call. I've just saved 100's of milliseconds in a game because I noticed a problem in a third party library.

Now this library is very good, don't get me wrong, at times it's brilliant. However it was designed for a small number of animation tracks. We use thousands of animation tracks. Huge numbers of the damn things. So the code was doing something it wasn't designed to do, and hence it was slow.

I added three lines of code and increased the speed by several thousand percent. The code was simple, finding the problem was a bitch. I'm talking a 20 year old bitch with massive PMT. blink.png

Would we have had that problem if we wrote it ourselves? Hell no!

Would we get the game out on time if we had wrote it ourselves...... probably not. sad.png

As frob mentioned you will find in certain cases that the motivation behind rewriting certain things (such as the STL or standard library) is related to needs specific to our industry.
High-level companies and individuals do it because they can write code that is faster, more suited to our needs, or both.
Electronic Arts explains the motivations behind EASTL here.

I myself use my own CVector and CVectorPoD, which is optimized for plain-ol’-data objects that can be moved in large chunks at a time (in memory resizes etc.) instead of one-by-one.
I also use my own MemCmp, which behaves the same as std::memcmp (and performs the same), but I also have MemCmpF which saves cycles by returning only true or false (as apposed to -1, 0, or 1, which requires a per-byte scan once a discrepancy between the inputs is found).

So when you are rewriting specific functions or classes, it typically boils down to:
  • Am I satisfying a specific need while retaining similar performance or better, or;
  • Am I simply improving performance significantly?
Boost is something you definitely do not want to use in your game projects.

In regards to actual libraries, things get more complex.
I originally wrote all my image-loading routines for .BMP, .TGA, .GIF, .PNG, and .DDS, which was a good experience and fun to do, but finally recently decided to add support for every file format ever to exist by just using FreeImage.
I don’t regret taking the time to reinvent a few wheels at least temporarily. Reinventing wheels is a great way to get a hands-on understanding of how things work, and if everyone never reinvented wheels then technology would improve at a snail’s pace.

Additionally, the whole reason I started my engine was to make a physics engine. I did make a miniature one and it was used in a ??????????? (Bakugan Battle Brawlers) game for Activision, which was a nice experience, but it was very basic and I will be using Bullet and PhysX this time around.


Ultimately, you need to decide if using a 3rd-party library is worth it for you based on what it brings and how much you care about your own personal balance on time, but nothing stops you from trying to make the same thing if you are interested in trying to learn that type of technology first-hand.

Libraries help you get things done faster but simple things such as string-compares are good exercises and larger things such as physics engines really help you understand how complex systems work under-the-hood.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

The main advantage of a 3rd party library is not that the code is written for you. The main advantage is that the code has been tested and debugged for you.

Do not underestimate that. You might look at a library and be horrified at the bloat and hacks and god knows what else, but most of the time, that boat and those hacks represent hours/day/weeks of work tracking down obscure bugs in strange environments.

Always be aware of that if you decide to write your own code instead of using a library.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

The main issue with pre-existing libraries is that they rarely do exactly what you want, and it's frequently the case that said library needs a lot of wrapping before you can even use its unwieldly API. You end up doing things like writing C interface layers to poorly documented image processing libraries that think they're cute because they use longjmp.

That said, as terrible as most libraries tend to be, there tends to be at least one that's a very close fit to your requirements. The hard part is finding it, and the harder part is testing it, because those libraries aren't typically the massively battle-tested ones.

The other thing to consider as well as the very valid points mentioned above is that the Unreal 4 code base is based on code that has been around for a long time. Sure Epic may claim that it has been rewritten form scratch but I highly doubt that they wrote every single line. If they have a string or a collection library that they have been using and maintaining since they release Unreal in 1998 then I really doubt they are going to replace it.

but I also have MemCmpF which saves cycles by returning only true or false (as apposed to -1, 0, or 1, which requires a byte-per-byte scan once a discrepancy between the inputs is found).

You'd be at most saving one comparison actually. As soon as you find a byte that's different (not sure if it compares byte by byte or word by word or whatever, but the case is the same regardless of how it does it), you check if the byte is bigger and return based on that.

If you have four bytes 0x01 0x02 0x03 0x04 and compare them to 0x01 0x03 0x03 0x04, as soon as you check the second byte you know the second string is bigger, so you return 1. If the second string was 0x01 0x00 0x03 0x04 you'd return -1 after checking the second byte. The first byte that differs is the most significant byte that differs, so that's all you need.

As for the actual topic, there's always a desire to roll you own when you realize you need something. You always need to be aware of the 80/20 rule, though: 80% of the work will be done in 20% of the time. The last 20% will take 80% of the time. That is to say, you can get most of the way in a short time, which may make you think that you saved a lot of time, but actually taking care of all the edge cases, testing, debugging and the like that would get you all the functionality you need will take you the most time. Deciding whether to roll your own or use 3rd party libraries needs to be carefully considered, there's no simple answer.

The first thing you should do is understand what your requirements are, exactly. The better you can define your requirements, the easier it is to make a decision. Then look at the documentation for the library. Does it match your requirements? How much work would you need to do to get it all the way there? Look around, too, don't just settle for the first library you find. After this you should have a list of libraries that match your requirements. Compare those to determine which one is the best. Does it have an active community of users (good for getting help if you're stuck, and probably means it is in active development), does it have good documentation, does it have a bug tracker, are there any disqualifying bugs still around, is the interface reasonable and easy to use, is the build system simple, etc. Once you have the best of these, compare what it does to how much effort it would take you to match the parts that you actually need.

If you are convinced you can do it better in less time that it would take you to learn the interface, go for it. Otherwise, use the library.

Of course, writing libraries is great for learning too. If time isn't an issue (meaning, generally, a hobby project), do it yourself if you want to. What I generally do is write from scratch things that I think are interesting, and use libraries for things that are boring.

For me it depends, when it comes to the standard libraries like vector, map, strings etc., I believe I couldn't do it better/ more efficient. When it comes to for example graphics handling I tend to just use the API and create libraries/ code around it myself. Not that I can do that better maybe then other available libraries, but it helps me in learning a lot.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement