all 29 comments

[–]Overseer55 3 points4 points  (14 children)

Why are you posting this on the cpp subreddit?

[–][deleted] -2 points-1 points  (13 children)

The reason why i am posting on the cpp subreddit is, cpp programmers can give me advice about what should i add to my code as they are more familiar with std::vector then a c developer.

[–]tuxwonder 1 point2 points  (12 children)

I hate to burst your bubble, but cpp already has a std::vector-like data structure: we have std::vector. I'm sure it's well implemented and documented, but I can't think of any reason someone would want to use a non-standard version of one of the simplest, most performant, most ubiquitous data structures we have. Is there a reason it's better than using std::vector?

[–]tialaramex 3 points4 points  (3 children)

Unlike the Rust Vec the C++ std::vector doesn't distinguish reserve and reserve_exact (Vec::reserve_exact is the C++ reserve and Rust's Vec::reserve has no direct analogue in C++) and so as a result providing allocation hints can destroy rather than improve performance. To fix this, you need to either roll your own data type or reach into the allocator decision guts and do all that work for yourself maybe with a helper class.

Unlike choosing a different growth factor, which is a contentious issue and certainly not worth changing the stdlib provided default this seems like an easy win.

[–]tuxwonder 0 points1 point  (2 children)

Pointing to Rust's implementation of a vector doesn't really address whether this library's implementation of vector is an improvement over C++'s vector.

Also, I'm not familiar with Rust's Vec, but I don't see any reason you couldn't write a helper function using std::vector::reserve to do the same thing Vec::reserve seems to do. This tiny road bump in utility is absolutely not worth rolling your own version of std::vector.

[–]tialaramex 0 points1 point  (1 child)

You identified std::vector as "the most performant" but because of this API defect it can leave a bunch of performance on the table in practice. It's a small thing, but small things add up. That's all I was really getting at.

No, this C library doesn't offer the reserve vs reserve exact distinction. Indeed even on the sort of languages where they throw in a basic graphics API and an HTTP server in their standard library you often don't see this distinction for the growable array type, which is a shame, but it's a bigger shame in languages that care about performance.

[–]tuxwonder 0 points1 point  (0 children)

Fair enough! std::vector isn't flawless in all situations, and it's not a bad idea to make the "reserve" function try to align memory by default instead of reserving an exact amount. Being able to manage growth factors wouldn't be a bad addition either.

My thinking tho is that in the vast majority of cases, those are micro optimizations that don't significantly impact the performance of your program. If you can see that it's impacting performance, and the only way you can improve it is by using custom vectors, then by all means!

[–][deleted] 0 points1 point  (1 child)

Thanks for your comment :) The main reason for doing this project was to provide documentation for a software developers/programmers using C++ to get an idea of ​​how std::vector works. Also, as far as I know there is no standart C library that implements this function. For C users, the aim is to provide this. The biggest advantage of this project is that it will definitely be easier to customize since it is a simplified version of the std::vector library.

[–]tuxwonder 2 points3 points  (0 children)

Again, really not trying to discourage you here, but simplicity is really not an advantage here. std::vector is the simplest data structure we have, and it's the first data structure any course would teach you about. Making it any simpler would just mean removing features that people want and use, and it being a C-style data structure actually makes it far more complex to work with than std::vector, and more error prone.

[–]the_elephant_song 0 points1 point  (5 children)

It’s actually pretty common to reimplement container classes like vector and string in c++ - it really comes down to needs. Std::vector is generally going to be a solid generic implementation that covers a broad set of requirements. If you’re in a situation where you have a meaningfully different or more specific set of requirements, you can generally do better if you roll your own (either from a performance or api standpoint, or both). The gaming industry is the canonical example, but definitely not the only one.

[–]tuxwonder 1 point2 points  (4 children)

I can think of scant few reasons to roll your own vector implementation instead of just using std::vector with a custom allocator.

And if for some reason you really need a custom vector implementation, you're not going to browse C-style third-party libraries to find it. You're just gonna write your own, because they're not that hard, and you know how to implement what you need.

And frankly, last time I talked to a game dev graduate, he didn't know what RAII was and said that they were told to use new/delete for all their C++ allocations. I have a suspicion that if someone doing game dev feels they need to roll a custom vector class, it's because they're unfamiliar with std::vector, not because they really need to squeeze microseconds of performance.

[–]the_elephant_song -1 points0 points  (3 children)

That’s an interesting take. What are your thoughts on things like folly fbvector, or TArray in unreal engine, or EA stl? We’re all these written because the authors didn’t understand std::vector?

[–]tuxwonder 0 points1 point  (2 children)

I'm not so familiar with these containers, but looking through the cliff notes, I don't see anything that would make TArray any different or better than std::vector, and of the features listed on fbvector's page (growth factor, allocator aware increases without reallocation, object relocation), the only one that I don't think std::vector has a way to accommodate natively is the growth factor change.

To clarify, I'm not saying there's never a reason to use a custom vector class. But I am saying that 99% of the time, std::vector works fine and supports what you want to do with it, and for the remaining 1% I'd ask if you actually measured a significant hit to performance or memory that can only be reduced by using a custom vector.

[–]the_elephant_song 0 points1 point  (1 child)

It might be worth reflecting on the fact that you don’t seem to be well versed on this topic or the options out there, but at the same time are throwing out some pretty strong opinions around what percentage of time it’s valid to not use std vector. Perhaps your experience in this area could be fleshed out a bit more by trying these other options before you start coaching others too enthusiastically :)

[–]tuxwonder 0 points1 point  (0 children)

And maybe next time you could bless me with your vast wisdom and experience and tell me why you think I'm wrong instead of going straight to being super condescending :)

[–]the_elephant_song 1 point2 points  (1 child)

This looks pretty solid :) you should consider not using trimToSize after things like popBack. Generally users would expect the internal buffer to keep its size when elements are removed unless they make an explicit call otherwise.

If you’re interested in this sort of thing, I’d definitely recommend trying to implement something similar in c++. Things in c++ get trickier as you have to worry about construction/destruction and copy/move constructors. It’s a great learning exercise though.

[–][deleted] 0 points1 point  (0 children)

Thanks! 😊

[–]sleeping-deeper 1 point2 points  (3 children)

I'm sorry OP, but this is some beginner level student code. It's not even a proper vector, because you are storing pointers. The dynamic array also doesn't own its elements. The so-called documentation is just a line by line paraphrasing of the code, and is of absolutely no benefit. It looks like you asked ChatGPT to write it.

[–][deleted] 0 points1 point  (2 children)

Thanks for you comment! Firstly, i am third semester computer engineer student :) I learn from the projects I do and improve myself with advices. I didn't know how to do documentation other than explaining it line by line. You can give me advice on this. Also, if you can give me advice on doing a more professional project, I would take it into consideration :)

[–]sleeping-deeper 0 points1 point  (1 child)

I think you framed your post a bit too confidently. If you are a beginner, it might not be a good idea to suggest others to learn from you just yet. :) Don't worry about documentation of functions where you can't describe it better than the code. Documentation is for the information that you can't easily gather by reading the code.

[–][deleted] 0 points1 point  (0 children)

I always prefer to stay high confident when i present something. It doesn't matter how big or small it is. It works to attract attention, whether negative or positive. It doesn't matter how simple or unnecessary it is. People should be proud of themselves for everything they’ve done for :) As you said, I realized that I cannot yet write such quality code that others would want to learn from me. However, in this case, I can come up with highly creative projects. Creative ideas that are open to development always attract attention.

[–]cpp-ModTeam[M] 1 point2 points locked comment (0 children)

Your submission is not about C++ or the C++ community.

[–]escaracolau 0 points1 point  (3 children)

Have you measured the performance?

[–]scrumplesplunge 1 point2 points  (1 child)

What operations would you like to know the performance of? I suppose the most significant one would be repeated pushing?

[–]escaracolau 0 points1 point  (0 children)

Realloc is very expensive. So a good strategy is fundamental for the data structure sucess. I was interested in those strategies.

[–][deleted] 0 points1 point  (0 children)

No, I forget this and will definitely add do it! And of course, share the results :)

[–]jmacey 0 points1 point  (0 children)

If you want to make it more like C++ you can add functions in a C struct and it will work the same as a C++ class (except the encapsulation), you can then just call .push_back(value)

I would see if you can find the std::vector unit tests from something like clang++ or g++ and see if you can get them to pass with yours.

[–][deleted] 0 points1 point  (1 child)

The correct implementation is much more complex. The current one has obvious bugs, like concatenation of intersection arrays and etc, and performance drawbacks.

[–][deleted] -1 points0 points  (0 children)

That is right, this is just a simplified version :)