Do you HAVE to loop through types?

Blitz3D Forums/Blitz3D Beginners Area/Do you HAVE to loop through types?

puki(Posted 2005) [#1]
I am going to have to make use of large groups of types for my RPG.

I'm no expert on types, having always loved arrays.

Now that I need to store so much more data in types, a previous problem that was not really a problem is becoming a major problem.

It seems (as far as I know) that to find a particular type, you have to loop through the whole group:

For blah.blahblah= Each blahblah

Next


This is no good to me. Can you set the start and end point of the For/Next loop, or does it always have to loop from beginning to end of the type?

If not, I'll have to subdivide my types - which won't be a major problem.


GitTech(Posted 2005) [#2]
type blahblah
        field nextBlah.blahblah
end type

startBlah.blahblah=first blahblah
endBlah.blahblah=last blahblah


currentBlah.blahblah=startBlah
while (currentBlah<>endBlah)
        currentBlah=currentBlah\nextBlah
wend




puki(Posted 2005) [#3]
Mmm, I don't like the way that you have to create a new field.

Going to have to rethink how I use types - I want to do as little searching/sorting as possible.


puki(Posted 2005) [#4]
In fact, looking at somebody else's code they put the whole For/Next loop for their types in side the main loop and have separate If/EndIf for each main thing they want to do.


Stevie G(Posted 2005) [#5]
Why not use an array of types like so ...


Type Test
 field x, y
end type

Dim MyType.Test( 100 )

For l = 0 to 100
  MyType(l)  = new Test
  MyType(l)\x = rand(10)
  MyType(l)\y = rand(10)
next



Then you can iterate through a specific number of them ...

for l = 12 to 22
  x = MyType( l )\x
next


Alternatively, depending on how you're doing things you could make use of the object & handle commands.

Stevie


puki(Posted 2005) [#6]
I was keeping away from Object and Handle - purely coz they are not totally legit.

The array of types idea is more like what I need to use. I can use standard types for some things and array of types things for others.

I'll have a play tonight.

Thanks guys.


PGF(Posted 2005) [#7]
The idea that you need to loop through types is a misconception that is reinforced seemingly every time that somebody asks about how to use them.

Somebody always posts an example of for ... each where they iterate through the whole list to find an item with a particular id or name. You can do that but you don't have to.

A type is a structure allocated in memory. It can be referenced by a simple variable, by an element of an array (with one or more dimensions), by a node in a list or stack or queue or tree or hash table ... by any data structure that you want to implement.

And a type instance can be referenced by more than one method.

The inbuilt type list that Blitz2D and Blitz3D give you is handy if you want to iterate through the whole list but it does not prevent or do away with the use of more appropriate data structures.

BlitzMax does not have the automatic inbuilt type list but of course you can implement your own list with similar behaviour in the type definition.

Object and Handle are another method. They expose the underlying data structure which Mark Sibly once said was just a C++ map of some type. Be aware that access to an instance through Object gets slower as the number of objects increases. I recall that it was something like O(log N) performance. That's good for general application but a custom access mechanism like say an array will be better in some situations. Don't search for something if you can locate it exactly.

So no - You do NOT have to loop through types.


jhocking(Posted 2005) [#8]
What he said.

Think of it this way: if you use the same name twice when loading meshes, you lose the handle to the first mesh, right? Well, the same is true of types. Thus, conversely, if you want to retain the handle for the type instance, just make sure to use a unique name. Now whenever you want a specific type instance, just use its name.

Of course, variable scope still matters. You could define the type instance's name as Global at the top of your code, or you can make sure to pass it to/from other functions.

The really cool thing is that you can refer to type instances directly by name or loop through all of them, as the task demands. Neither method interferes with the other, giving you greater flexibility.

---

Incidentally, Object and Handle are probably not going away any time soon. I've been using those commands for years with no problem, and at this point Blitz3D isn't changing much more.


octothorpe(Posted 2005) [#9]
Maps (aka associative arrays, hash tables) have O(1) complexity, which is why they are so awesome. See the Wikipedia articles on Associative Arrays, Hash Tables, and specifically the [a http://en.wikipedia.org/wiki/Talk:Hash_table#O.281.29_should_be_O.28k.29_k_being_the_key-length]talk on O(1)[/a].

GitTech's example doesn't need a new Field, you can use the After command. I wouldn't recommend this approach as it only half-solves the problem - you get multiple linked lists per type, but you have to keep track of start and end nodes, you can't have the same object in two lists, andyou have to make sure that nodes get entered into the correct "list" via Insert.

I've implemented some Container Classes which make it easy to store collections of objects using Object() and Handle(). They circumvent the drawbacks of both builtin lists and typed arrays.


GitTech(Posted 2005) [#10]

GitTech's example doesn't need a new Field, you can use the After command.



Mmm, I had forgotten about the "After" command :-). Thanks for refreshing my memory! :-)


puki(Posted 2005) [#11]
Thanks for all the responses.

Still, not sure of the path to take (in terms of how I want to access and manipulate my data) - a lot of testing to do to see what way to go.

Of course, I could just be a cheeky little sausage and go back to my sluttish use of arrays.


Ross C(Posted 2005) [#12]
It does depend on how many type objects you have. Looping through type objects is lightning quick. As for Object and Handle commands. There about legit as they are going to get. I don't think blitz3d will be receiving too many upgrades, and there's no real reason to remove them. And, again, depending on how many types you have to loop through, using them, might not be slow at all.


jfk EO-11110(Posted 2005) [#13]
I think Stevies Examle is the best of both worlds. While it allows you to access things with a simple index, you still got some kind of custom data container.

It's a fact you can do a lot of mistakes with types. some people create a number of types and then add a field containing the index. Every time they need to access eg. the object with the index 123, they need to loop trough all objects and check the field containing the index. This is rubbish.

When indexed access is required, I'd suggest to use Stevies code.

That said I'm not a Types expert at all, and I try not to use them whenever possible. After all I still think not using them will help you stucture your app in a way that runs much faster.

EG I made a VIS computing app some time ago. Every Surface was colored with a unique Color (ICU, Idendification by Color Uniqueness), beginning somewhere near black.
The App then used Readpixelfast to determine the visible surfaces. Now I was capable of using the Color right as an Array index. This is what I call straight forward.

Also, from the benchmark test I made it seems simple read and write access to int types fields is about 2,25 times slower than array access (using arrays of types, like Stevie suggested).
The benchmark did a for loop and then subtracted the time for the same for loop not containing the Array/Types access.

So personally I think it's best not to use types whenever you can.


octothorpe(Posted 2005) [#14]
Micro-optimization should be done after performance bottlenecks are found; otherwise, you sacrifice clean code and hours of work for a few measley CPU cycles. Choosing better algorithms can often make huge performance improvements, but it's difficult to test changes if you've painted yourself into a corner by micro-optimizing early. Donald Knuth put it plainly: "Premature optimization is the root of all evil."

If you're masochistically obsessed with squeezing every last drop of performance out of your code, perhaps you should try C. This is Basic, and we should try to keep it so.

I strongly recommend that people choose the simple route at first. If you find that your clean code is costing you too much performance, turning an encapsulated solution into an optimized one is easy; going the other way is usually impossible.


jfk EO-11110(Posted 2005) [#15]
I'm not talking about Micro Optimation, but about a diffrent way of thinking. If you do it this way in the first place, where's the problem? I was using Assembler a lot, maybe that's why I prefere a simple piece of Ram from a types construct.

And the definition "clean code" really depends. A lot of people seem to think their code is better when it looks object oriented. And at the end of the day they often have nothing but a bunch of attempts.

I am not masochistically obessed or something, I only said: Don't use types if you don't have to use them. This can be translated as: Don't use types only to have used them, or: Don't use types when there is no need to use types for a specific implementation. Why would you use "Print" when there's no need for printing? Because it's clean?


big10p(Posted 2005) [#16]
There may well be a small speed hit from accessing type fields as opposed to simple arrays, but in most realworld situations, this 'speed hit' is nothing but completely insignificant.

However, the tradeoff for this speed hit by using types is anything but insignificant. The advantages of using types as opposed to multiple arrays to hold relted data are too many to list here, frankly. Type-like structures were invented for a very good reason.

It comes down to this: are you writing code for humans that can be easily read/understood/managed, or are you writing code soley for the benefit of the CPU? There are, of course, occasions where the latter is desireable, but the former should be the default.

TBH, some peoples' dislike of types (and all the benefits they provide) astounds me.


jfk EO-11110(Posted 2005) [#17]
Personally I just think types are definitively NOT the holy grail, au contraire, they lead to lazy programming habits and the programmer gives the total control out of his hands.

"For Each" - I mean, what is that anyway? It's a mess. Throw a lot of stuff into the sandbox, and then do something with EACH one of them. It's called delegation and leads to rumours and revolutions, or in terms of computer speech: to bugs, lags and instabile apps.

Did you notice how long it took until somebody actually relaized the bug in the types that was fixed with version 1.91? Don't tell me you know what's going on when you don't realize such a bug for years.

ok </ :P>


octothorpe(Posted 2005) [#18]
I'm not talking about Micro Optimation, but about a diffrent way of thinking. If you do it this way in the first place, where's the problem?


How is using several arrays in place of an array of type objects for the purpose of saving a few cycles not micro-optimization? The problem is that several arrays don't provide you with the encapsulation that one array of objects does.

(Note that in most languages, field lookup is done at compile time and using structs (type objects) won't cost you a cycle.)

A lot of people seem to think their code is better when it looks object oriented. And at the end of the day they often have nothing but a bunch of attempts.


Your argument against object-oriented programming is that it isn't effective? How did you come up with this theory? A lot of professional programming shops use object-oriented techniques expressly because doing so saves them money. I suggest you read a book on the subject before making any more wild claims.

"For Each" - I mean, what is that anyway? It's a mess. Throw a lot of stuff into the sandbox, and then do something with EACH one of them.


It's called a linked-list, a fairly standard computer science concept.

delegation ... leads to ... bugs, lags and instabile [sic] apps.


Delegation makes the world go 'round, my friend! The human brain can only deal with a certain amount of complexity at a time; to make a computer do anything reasonably complex we encapsulate code and then delegate work to it. When you call a function, you're delegating. When you use a compiler, you're delegating.

Really, the only way you could make that argument would be if you only used your own assembler code. Since you bought a Basic compiler (one of the highest-level languages around!) you automatically lose.

Please insert coin to continue.


jfk EO-11110(Posted 2005) [#19]
I'd insert my 2 cent here, but it starts sucking. I mean, why don't you let people program the way they like to? Why has it got to be your way, your god and your religion?

The fact that I bought Blitz3D doesn't mean I am not using Assembler too. And there was no "argument against object-oriented programming", but one against pseudo-object-oriented basic. I used Java for some time, it's not the way that I don't know what I am talking about.

I actually released some things, eg, the most complete FPS game engine written in Blitz3D known to the community. And surprise I didn't use types there. Now show me what you did. No offence, but eh, seriously.

Ok, this was really my last 2 cents. IMHO people may code the way they want. If they choose to go a not so common way, for whatever reason, let them do so.


octothorpe(Posted 2005) [#20]
Sorry, this machine only accepts quarters.