Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Functions VS Gosubs

Author
Message
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th Apr 2004 10:31
Why are functions so much slower than using subs and gosubs?
I was messing around trying new things and I wrote 2 programs exactly the same but in one I used subs and gosubs and in the other I used functions in place of the subs. My frames per second dropped by appx 15 using functions. The functions did not have any return values I was just using them to do stuff.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Pheonixx
20
Years of Service
User Offline
Joined: 6th Oct 2003
Location: Columbus, Ohio
Posted: 19th Apr 2004 10:52
Well functions require passing data... they are much faster if you use pointers.

When you use a GOSUB, you are still withen the main source, and all local variables are readily available to use.

When you use a FUNCTION, you are jumping out of the main source into a sub routine, and 'passing' it values. Now if all of the values you use in your functions are declared as GLOBALS, this will speed up the process, but run like hell on larger programs when the amount of used variables start to range in the thousands.

The best thing to do, is make a POINTER, and 'point' to the local variable that you want to 'pass' to the function. By sending a pointer, you are only sending a reference to the variable, instead of the intire variable.

This might not seem like a big deal, when you are looking at one or two Integers. But when you want to create a function that reffers to an intire array, a Pointer is the way to go.

There is one last note about Gosubs:

If you use a gosub, you can get caught with all kinds of nasty problems in your code. Almost anything in computer programming can be done in more then one way. You are much better off to never use them except for troubleshooting, or moving massive amounts of code to the bottom of your program, to increase readability.



All said, I still strongly recommend not using it until you are very experienced on reading code.

Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th Apr 2004 11:13
Thank You. I tried passing the variables in and making all variables that would be passed (in or out) global(which was a little faster). I'll have a look into pointers. If pointers don't speed it up alot then I may have to stick with subs as the speed difference between the two methods is to great. Loosing 15 frames out of 70 is just too much. And my program is only 800 lines long comments included as it is mostly graphical at the moment. The only things I have done are Loading all models with desired apperance, gravity, a basic jump code, weapon changing, ingame light level adjustment, and collision (NCG).

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
walaber
20
Years of Service
User Offline
Joined: 22nd Oct 2003
Location: Los Angeles, CA
Posted: 19th Apr 2004 13:01 Edited at: 19th Apr 2004 13:01
that'S pretty amazing. My current project has about 6000 lines, and at least 50 functions!

I wonder if I switched it to gosubs, how much it would speed up

I noticed the Roomwar source code was all Gosubs too...


but I like functions so much... they make me feel like a [b
real[/b] programmer

Go Go Gadget DBPRO!

Athlon XP 2400+ || DDR-SDRAM 1GB || Nvidia GeForce 4 Ti4200 AGP 8x 128MB
Scouseknight
20
Years of Service
User Offline
Joined: 15th Mar 2004
Location: Bootle, Merseyside, UK
Posted: 19th Apr 2004 13:12
I must confess I think Functions are great and I use them generously - I am wondering now about changing my current project to gosubs to see how it performs - there are only a handful of functions that return anything in this project the majority are just splitting my code into modular segments.

Rob K
Retired Moderator
21
Years of Service
User Offline
Joined: 10th Sep 2002
Location: Surrey, United Kingdom
Posted: 19th Apr 2004 17:02
That is odd.

Can you provide some code showing the performance difference.

I just did some tests with simple functions & gosubs

The difference in timing was absolutely minute.

BlueGUI:Windows UI Plugin - All the power of the windows interface in your DBPro games. - Plus URL download, win dialogs.
Over 140 new commands
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th Apr 2004 17:14
Right now I am late for work but when I get home I will post both source codes and media if you want.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Pheonixx
20
Years of Service
User Offline
Joined: 6th Oct 2003
Location: Columbus, Ohio
Posted: 19th Apr 2004 23:18
Quote: "I just did some tests with simple functions & gosubs

The difference in timing was absolutely minute."


simple functions

Try passing an entire array to a function, you wont see any difference in performance until you start working with larger numbers.

An Int is about the same size as a Pointer

An array can be a thousand times larger then a Pointer

A Global, can lead to sloppy programming and mis managing variables.

A Global, can make reusing functions for other purposes difficult.

Rob K
Retired Moderator
21
Years of Service
User Offline
Joined: 10th Sep 2002
Location: Surrey, United Kingdom
Posted: 19th Apr 2004 23:36
Passing an array to a function by-value is not a good idea as you'd have to copy the entire array out. Since you cannot pass values by-reference, I would stick with global variables or pointers. DBPro has very limited pointer support at the moment though.

And an integer is exactly the same size as a pointer, certainly on 32bit CPUs. I don't know about 64bit (the pointer would certainly be larger, but I don't know if ints would still be 4 bytes or if they would become the same length as a pointer).

DBPro does not have native 64bit support so that's not really an issue.

BlueGUI:Windows UI Plugin - All the power of the windows interface in your DBPro games. - Plus URL download, win dialogs.
Over 140 new commands
Pheonixx
20
Years of Service
User Offline
Joined: 6th Oct 2003
Location: Columbus, Ohio
Posted: 19th Apr 2004 23:40
Right, I didn't pull out my variable usage chart, so I couldn't remember if they were equal or not.

Tomy
20
Years of Service
User Offline
Joined: 25th Dec 2003
Location:
Posted: 19th Apr 2004 23:55
I wonder why you can't pass values by-reference...
That would be something that i'd like to see in a future upgrade
I always use that in C++ and we made some speed test at school on some REALLY lame computers and the difference was huge
I know you can do it with global variables but the other way is ...erm.. cooler


GameVisions Softwares - http://www.gamevisions.cbj.net
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 04:02 Edited at: 20th Apr 2004 23:39
O.K. the media included is 35MB so that is a bit too big to upload.
So I will post the source codes first. Then possibly come up with some way to do the media if need be. But since I am new to DBP and it is likely something that I have done wrong .... posting just the sources should tell me what I want to know. I hope. Here is the program with subs. I get 70 FPS when it loads and you do not touch any controls. I use this to average by because the level is very laggy (it is 1500 objects made by the csm importer) .

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 04:07
O.K. here is the function version. It is not exactly as I had it last night as I accidently saved over it. But it will be close enough to show my problem. I get 55 fps with this one.

[Edit] When I move around the variables that = timer() outside of functions my scan times are being reported as alot faster. I wonder if this is in some way throwing the fps command off as well?

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 04:10
All criticism of the code is greatly appreciated. Both good and bad remarks I promise you will not hurt my feelings.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Peter H
20
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 20th Apr 2004 04:50 Edited at: 20th Apr 2004 04:50
you call that code????!?!?!?!?! ....(j/k)
[edit] i don't think anybody has had the time to look at the huge code snippet yet...


Formerly known as "DarkWing Duck"
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 04:56
Sure just make fun of the newbie ..... sniff sniff and lip trembles.



"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 05:16
Quote: "if 1stload=1 then loadtimeend# = timer(): inc 1stload,1"


I'm not sure if this is legal in DarkBasic.. it may well be. But in most programming languages, variable names are not allowed to begin with a numeric digit.

E Unibus Plurum
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 05:20


This may not be a speedy operation. These 'constants' may be getting initialized inside the function each time you call it. It doesn't seem right that constants should do that.. but you never know.

Perhaps leaving these at the very top of the file (if they stil work correctly that way) would be something worth a try.

E Unibus Plurum
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 05:27 Edited at: 20th Apr 2004 05:34
Cool. Thank you. I will check into the constants.

Quote: "if 1stload=1 then loadtimeend# = timer(): inc 1stload,1"

"I'm not sure if this is legal in DarkBasic.. it may well be. But in most programming languages, variable names are not allowed to begin with a numeric digit."

I wasn't sure either if this was legal so I tried it and it worked.

[Edit] I moved all constants outside of functions and to the top of the file ( only called once per program). But this didn't speed it up any that I could tell probably because after I moved them I noticed that I was only calling most of those functions once.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Black Hydra II
20
Years of Service
User Offline
Joined: 26th Nov 2003
Location:
Posted: 20th Apr 2004 05:51
Functions all the way!!

I am unsure on the grounding of performance but in general terms they are much more reliable. They are self contained so they can do specialized tasks without trouble from other sub routines.

"Damn had to remake account!" direct quotation from previous account.
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 05:56
Yes.. I noticed that after I posted... sorry for the false alarm.

Nicely laid out code though. Very modular and easy to read.

Just for fun.. have you tried cutting and pasting the global declarations from the new file to the top of the old file? I haven't tried it with your code (didn't DL the media), but it might be that global variables are inherently slower. It wouldn't take long to try that.

E Unibus Plurum
kenmo
21
Years of Service
User Offline
Joined: 7th Sep 2002
Location:
Posted: 20th Apr 2004 06:12 Edited at: 27th Jun 2012 06:15
This isnt aimed at anyone in particular, but gosubs are indeed faster than functions. I made an image editor in DBC, using a memblock to perform all the effects. To do most effects, I would have to read every pixel, I would have to convert 16-bit images to 24-bit to get the RGB, then back to 16-bit to put it back into a memblock...

Using 16-to-24 and 24-to-16 FUNCTIONS, using a simple greyscale effect (for example) could take several seconds. But when I moved the calculations into the main source, out of functions, it is almost instant.

I may whip up a small greyscale program to illustrate this...
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 06:43 Edited at: 20th Apr 2004 06:53
@Ideajuice Thank you. I was just trying that I get all kinds of errors when pasting the globals into the sub/gosub code. Doh! I just learned something else you can't use global declarations on a variable that is assigned as a constant to an equation like NumLevelObj+12 it gives you an errror. See code.


@kenmo sounds interesting. I'd like to see that.

[Edit] I give up how do you put the code in those white code snippet boxes?

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Pheonixx
20
Years of Service
User Offline
Joined: 6th Oct 2003
Location: Columbus, Ohio
Posted: 20th Apr 2004 07:06
Okay mate, one biggy

You need to use the END command when using functions or gosubs. Later on if you get out of that loop, your program will then go thru and execute the first gosub, hit the return, crash, and ask you what you are returning from.





Other then that, nice layout.

Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 07:08
Thank you. I'll add the end commands now.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 20th Apr 2004 16:41 Edited at: 20th Apr 2004 17:06
O.K. Problem found. It was the global variables making the difference
because my all my system resources were tapped out I guess. If I load the globals into my sub/gosub code it runs at 57 fps. If I leave the codes just as I posted them (plus the end command after both loops) and shut down the 50 million programs (well may be a few less than that) running in the background the gosub version runs at 71 fps while the function code runs at 69fps. I can live with this small fps drop. Thank you for all the help.

Now does anyone know why my attempt at time syncing my gravity doesn't work?

[Edit] I think I know why grav syncing doesn't work now. I'll try and fix it when I get home.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 16:50
To put code in the edit boxes, make sure your forum profile is using the 'fancy editor' or whatever it's called, then highlight something you've typed and press one of the formatting buttons above the edit box.

The highlighted section will have some tags put around it that are kind of like HTML. You can type these tags in manually once you get familiar with them.

E Unibus Plurum
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 16:59
Pure conjecture.. but accessing global variables probably requires the code (at the machine code level) to load the address of the global variable area into a register, and then retreive the value of the variable as an offset from this pointer.

It's likely that variables local to a function, or variables explicitly passed into a function, are allocated and accessed on the stack, and this would mean that there is already a register loaded with the base address of the memory area where those variables are stored.

If that is the case, then it would require a lot more instructions each and every time you do anything with a global variable in a function. It probably also means that even outside of functions, using global variables is slower than using 'normal' variables.

It might be interesting to look at the difference in size between the two versions. If the function/global based version is much larger, that would tend to indicate that the compiler is indeed producing less efficient code for the global variable access.

E Unibus Plurum
TheOneRing
20
Years of Service
User Offline
Joined: 28th Aug 2003
Location: Right here.
Posted: 20th Apr 2004 18:27
@Ideajuice: Not so sure about that. I do know, however, that function do have a couple of drawbacks.

1. The function's parameters have to be pushed on the stack every time it is called. This can be time consuming, especially with function that have many parameters and/or complex data types (i.e. UDTs).
2. Although not likely to happen many calls to functions without returning from them (i.e. recursive algorithms) can overflow the stack. Remember, you have a specific amount of stack space available. How much that is for a DBP program I'm not sure...

Global variables are simply stored in a memory location, so their access is fairly quick.
Ideajuice
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Cyberspace.. out near the edge
Posted: 20th Apr 2004 18:42
Good points TOR.

In this case though.. we are talking about the difference between using global variables and normal variables without using functions at all.

In his gosub based version, which has no functions at all, he is getting a performance hit simply from changing his normal non-global variables into global variables. The main slowdown here was not function call overhead since he gets the same slowdown without the function calls (well he gets a 1 or 2 percent drop from the function calls which is a little more realistic than 20 to 30 %).

Pushing parameters onto the stack for a function call happens only once each time the function is called, but apparently, accessing global variables incurs a performance penalty every time you access them. This could equate to every single line of code being slower, which is much more likely to cause a massive 20 to 30 percent drop like he was noticing.

E Unibus Plurum
TheOneRing
20
Years of Service
User Offline
Joined: 28th Aug 2003
Location: Right here.
Posted: 20th Apr 2004 19:01
Sorry.. That's interesting. Has anyone else tested this?
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 21st Apr 2004 04:29
Code Repost of gosub version.

"People don't fail ..... they stop trying." Specs. P4 2.8GHz 800 FSB | 512MB DDR333
GeForce FX 5200 AGP 256MB | Windows XP Pro Full
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 21st Apr 2004 04:34 Edited at: 6th Sep 2004 09:57
Code Repost of function version.

Tapewormz
21
Years of Service
User Offline
Joined: 15th Sep 2002
Location: Winnipeg, Mantoba, Canada
Posted: 21st Apr 2004 04:46 Edited at: 21st Apr 2004 04:47
Do you have a sync in your function and in your main loop? Functions don't drop my framerates at all...Whoops, my bad...You posted code...Sorry.

Quote: " Timesoft - Your wife is death. How? NO idea.
But it is murder. REVENGE!!!!!!!!!"

Hands down the funniest synopsis for a game ever. All your base are belong to us!

Login to post a reply

Server time is: 2024-05-28 11:13:43
Your offset time is: 2024-05-28 11:13:43