   string based objects and performance tips
  Instead of usint traditional objects like: object MyObject;MyObject.load() (etc.. just an example)Ive tried to make function that will add object and name them after a name (LPCWSTR). Lile textures and sprites etc.SpriteManager::SpriteManager(LPDIRECT3DDEVICE9 device) {counter = -1;D3DXCreateSprite(device,&sprite_p);logo.open(L"C:\\logo.txt", std::ios_base::out);}void SpriteManager::SetSprite(LPCWSTR generic_name,LPDIRECT3DTEXTURE9 textura) {counter = counter + 1;sprite_vector.resize(counter+1);sprite_vector[counter].id = generic_name;sprite_vector[counter].text = textura;void SpriteManager::SetPosition(LPCWSTR generic_name,D3DXVECTOR3 pos) {for (int i=0 ;i<counter+1;i++) {if(sprite_vector.id == generic_name){    sprite_vector.pozitie = pos; i = counter+2;}}}}Funtions are like:sp_manager = object to a sprite class that have those funtions.//Ill do that in the render function:sp_manager->CheckColission(L"slot_1",L"item_1");//orsp_manager->GetPosition(L"slot_1",&pos8);//orsp_manager->DrawSprite(L"all_sprites");That is just an example. The problem is that i started to use that technicue so much so Im afraid if will cost me performance in the future. Now im doing just an drag&drop inventory so I cant complain any framedrop. Is this performance safe ?Thanks..[Edited by - Azzazelus_13 on September 11, 2007 9:37:00 AM]
  There's a nasty little line in there, which is this:sprite_vector.id == generic_nameThis will compare true if and only if the two string pointers are exactly the same. However, when you write L"Something" in your code twice, there is no guarantee that the pointers will be the same (some compilers do, others don't). Therefore, if you write:sp_manager->SetSprite(L"slot_1", texture);sp_manager->SetPosition(L"slot_1", pos);Then the second line may or may not change the object created by the first line, depending on your compiler and compiler settings. This is probably not what you want.As for performance, you're basically traversing an array looking for a value every time you reference an object. This is bad, because it means quadratic complexity (if you have a thousand objects, your code will be a thousand times slower than standard pointer- or index-based code).In the end, if you intend to go on with this approach, there are two things you must know:It's better to use enumerations instead of strings. For instance:enum { SLOT_1, SLOT_2, OBJECT_COUNT };This allows you to use direct indexing (converting enums to integers, and using that as an array index) to find objects, greatly improving performance while keeping the same underlying program structure. Plus, you can allocate a "big enough" array initially by using the compiler-evaluated OBJECT_COUNT value.This approach is purely procedural. There's nothing wrong with it (though you have to be careful with what you're doing, as usual), just don't delude yourself into thinking that you're doing object-oriented programming, because you're not. ;  Using it for everything will cost performance unfortunatly.  I would recommend reserving this type of thing for high level things like whole entities and just accessing lower level things like position in the classical way: object.position = pos;As a side note, your implementation is very inefficient.  You're searching through a vector to find a name.  Use a map instead:std::map< std::string, Sprite > spriteMap;spriteMap["someString"].position = pos;   ;  Thanks for the answers.I know this is not OOP but i wanted to make this for some reasons: - easy management of objects. Lets say Im adding items to an inventory with a function. I increase the object count then i can make functions like lets say "ChangeDepthBackToAll();" or "LoadAllTextures()"..instead of making another 'framework' in the game..  - I can easly add objects anywhere.. etc.So If I use the same thing but with numbers instead of strings is ok?   ;Quote:Original post by Azzazelus_13I know this is not OOP but i wanted to make this for some reasonsI'm not criticizing your choices. Object-Oriented is by no means the only paradigm out there (it's one of the paradigms I use the least myself) and procedural programming has been shown to work time and time again. You just have to make sure that you know the shortcomings of your approach.Quote:So If I use the same thing but with numbers instead of strings is ok?Yep.;  Thanks again.What about declaring object like device and texture in the class so it could be copied from the construcor? Smth like :class texturemanager { texturemanager(LPDIRECT3DDEVICE9 device); LPDIRECT3DDEVICE9 dev;}texturemanager::texturemanager(LPDIRECT3DDEVICE9 device) {  dev = device;And other objects like text_manager pointer etc.. declared in the same class.   ;  1) If you're going to use strings, use real strings (std::string).2) The natural structure for this sort of thing is std::map, as pointed out.But if you want to learn to use vectors more effectively,3) It doesn't make sense to .resize() a vector every time you want to add something. Instead, use .push_back() to add things to the end: it will take care of any necessary resizing automatically.4) The way you handle loop indices is very strange. It makes more sense to:- start the counter at 0, so that it always actually *counts the number of things*. (Except that you don't need to do that: just use the .size() of the vector.)- Assign to element counter-1, or else assign before you actually increment the counter (except that again, you don't need any of that.)- Loop while i < counter, rather than counter + 1, because the counter is now actually the count of items.- *break* from a for-loop, instead of simply arranging for its loop condition to be violated. The keyword is there for a reason.That looks like:// Notice that I'm only fixing the way you use the vector here: you should// still ignore all this to use a map and real strings :)SpriteManager::SpriteManager(LPDIRECT3DDEVICE9 device) {// no counter: the .size() of the vector becomes a counterD3DXCreateSprite(device, &sprite_p);// It's actually a bad idea to hold an open stream as a data member// of a class, but I would have to see what you're doing with it in// order to fix thatlogo.open(L"C:\\logo.txt", std::ios_base::out);}void SpriteManager::SetSprite(LPCWSTR generic_name,LPDIRECT3DTEXTURE9 textura) {// no manual resize: instead, we construct an instance firstsprite_vector.push_back(Sprite(generic_name, textura));// Here, I am assuming Sprite has an appropriate constructor; it should :)}void SpriteManager::SetPosition(LPCWSTR generic_name, D3DXVECTOR3 pos) {for (int i = 0; i < sprite_vector.size(); i++) {if(sprite_vector.id == generic_name) {sprite_vector.pozitie = pos;break;}}}