Jump to content
IGNORED

To Optimize, or to Scrap...


Opry99er

Recommended Posts

Well... it took several hours of work, but the following was accomplished today:

 

*Eliminated 106 lines of code from my program

 

*Completely re-wrote the ENTIRE Menu system (saving only labels)

 

*Saved 2,138 BYTES of PROGRAM SPACE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

Wowza!!! Great feeling right now!

 

 

Maintained 100% functionality... Only "downgrade" is there is a slight delay in displaying names of spells in the SPELLS menu... This is due to some fancy math and loops I put in there to READ from some DATA lines... Doing this saved me 32 lines of code, so I think I can live with it for now. :) I will take another look at it tomorrow and see if I can optimize it.

 

 

So... Back to Topic title.... I SCRAPPED IT!!!

Edited by Opry99er
  • Like 3
Link to comment
Share on other sites

How would you optimize this code to make it faster? It currently takes almost 3 seconds for whatever reason.....

 

 

 

2610 DISPLAY AT(15,1):" "
2620 RESTORE 3500
2630 FOR I=16 TO MN(C)+15
2640 READ TX$
2650 DISPLAY AT(I,1):TX$;
2660 NEXT I
.
.

3500 DATA 1) HEAL (10 MP)
3510 DATA 2) CURE (15 MP)
3520 DATA 3) LIFE (20 MP)

Edited by Opry99er
Link to comment
Share on other sites

**Background, it WAS a big long mess, wherein MN© was checked and control passed to one of 3 subroutines which displayed either 1,2, or all 3 of these...

 

This was part of my rewrite to save bytes and simplify code.

 

I may have gotten too "cute" with this one...

Link to comment
Share on other sites

 

How would you optimize this code to make it faster? It currently takes almost 3 seconds for whatever reason.....

2610 DISPLAY AT(15,1):" "
2620 RESTORE 3500
2630 FOR I=16 TO MN(C)+15
2640 READ TX$
2650 DISPLAY AT(I,1):TX$;
2660 NEXT I
.
.

3500 DATA 1) HEAL (10 MP)
3510 DATA 2) CURE (15 MP)
3520 DATA 3) LIFE (20 MP)

Try removing the calculation from the FOR declaration... the easiest way is to determine how many you're going to display to start with, like follows:

 

N = 3 + (MN© < 20) + (MN© < 15) + (MN© < 10)

FOR I = 1 TO N

...

 

The logic checks above will return 0 if the statement is false, and -1 if true. So if your magic points aren't high enough to cast any spells, N becomes 0 and the FOR loop is skipped entirely.

 

Thinking back, most CRPG's would display ALL spells and just say "You don't have enough magic points" if you tried to pick one you didn't have enough for. That may be the best way to make this faster; just print them all and only do your magic point check AFTER the player has selected it.

Link to comment
Share on other sites

For sure... Thanks for the tips!

 

In this case, however, the check is determining what to display depending in WHO will be casting (irrespective of MP)... This is where one player can cast 3 different spells, another two, and another just 1. :)

Link to comment
Share on other sites

MN (meaning magic number) indicates the number (0-3) of spells a member can cast.

 

It is an array with 4 values... In this case, I want to ONLY display the castable magics of each player, so I used this formula.

 

The FOR I=16 TO MN©+15 is simply to give me the proper number of.times through the loop, while using "I" as the row for display.

 

Like I said, I may have gotten too cute... It works well, but at what cost?

Edited by Opry99er
Link to comment
Share on other sites

Thinking back, most CRPG's would display ALL spells and just say "You don't have enough magic points" if you tried to pick one you didn't have enough for. That may be the best way to make this faster; just print them all and only do your magic point check AFTER the player has selected it.

That's how I do it too. :)

Link to comment
Share on other sites

MN (meaning magic number) indicates the number (0-3) of spells a member can cast.

 

It is an array with 4 values... In this case, I want to ONLY display the castable magics of each player, so I used this formula.

 

The FOR I=16 TO MN©+15 is simply to give me the proper number of.times through the loop, while using "I" as the row for display.

 

Like I said, I may have gotten too cute... It works well, but at what cost?

 

Ahh... in that case, remove your 16 and +15 from the FOR loop, and just put that into the DISPLAY AT instead. That way it's only pulling the reference and not actually doing calculations.

 

That may get you back a bit of performance.

Link to comment
Share on other sites

Thanks...

 

I guess I am just struggling with how to get it to display the proper number of lines then...

 

If my mage is the ©, then I need three times through the loop... If thief, then I only need 2, etc.

 

Something like

 

 

X=16

FOR I= 1 TO MN©

READ TX$

DISPLAY AT(X,1):TX$;

X=X+1

NEXT I

 

Would this net some speed, you think?

Edited by Opry99er
Link to comment
Share on other sites

The loop limit is only evaluated once, so I would not think that is the bottleneck. I Think the READ, with the possible invocation of garbage collection in VRAM, is what is taking the time. I would bet you would get a speed increase by using a string array instead of the DATA statements. Of course, that moves storage to VRAM (I think) instead of program storage.

 

...lee

Link to comment
Share on other sites

Thanks...

 

I guess I am just struggling with how to get it to display the proper number of lines then...

 

If my mage is the ©, then I need three times through the loop... If thief, then I only need 2, etc.

 

Something like

 

 

X=16

FOR I= 1 TO MN©

READ TX$

DISPLAY AT(X,1):TX$;

X=X+1

NEXT I

 

Would this net some speed, you think?

Check to see if this is faster, I have no idea:

X = MN(C) + 15
FOR I= 16 TO X
READ TX$
DISPLAY AT(I,1):TX$;
NEXT I

But I would write it like this if TI BASIC lets you. There is some overhead involved with added line numbers.

 

X = MN(C) + 15
FOR I= 16 TO X :: READ TX$ :: DISPLAY AT(I,1):TX$; :: NEXT I
Link to comment
Share on other sites

Thanks for the ideas, guys.

 

I think the most likely culprit, as Lee suggested, is the READ.

 

I will try out all the suggestions you guys have given me, but my money is on a string array for optimum speed increase.

 

:)

 

Once again, you guys rock.

Link to comment
Share on other sites

Read has to scan through the lines looking for the data statement at least at the first read.
If TI supports RESTORE (I think that's the command) you can RESTORE # and then BASIC should know where the data is.
In theory... I've never tried it

Link to comment
Share on other sites

Owen - string arrays are pretty handy. Most of Heatwave's prompts and text are located in one string array for quick and easy access.

 

When the BBS starts up, it loads all 100+ strings from a single dis/var80 file, editable in FunnelWeb (or any similar editor). You can print the DV80 file with line numbers using the "L" option, if I recall correctly, so that you can reference the string array numbers.

 

If you have string space to spare, this might be a good alternative for you. It would also free up precious programming space.

 

Quick and dirty load from DV80 file:

 

 

10 DIM A$(100)   !space for up to 100 lines in the file
100 OPEN #99:"DSK1.YOURDV80",INPUT
110 A=0
120 A=A+1 :: LINPUT #99:A$(A)::IF EOF(99)<>1 THEN 120
130 CLOSE #99
140 FOR X=1 TO A::PRINT A$(X)::NEXT X

 

Note: LINPUT is used here in case commas or other delimiters are found in your string.

  • Like 1
Link to comment
Share on other sites

@James:

 

Yea, I am using RESTORE in this code. :) I think the whole segment is third post from the top of the page.

 

These are currently my only DATA lines, so initially I didn't have a RESTORE. But, seeing the speed problem, (just like you suggested) I added RESTORE... It did not seem to speed up execution by much if at all.

 

@Tim:

 

Yessir!!! I have recently discovered the magic of arrays, string and numeric!

 

Currently all my data (other than the current DATA lines I am struggling to manipulate) is drawn from a DV file on disk. ;)

 

My disk code looks much like yours there, only without the EOF part... I am referencing the records in a loop and just feeding them directly into my numeric and string arrays at the start of the program.

 

Really is cool... :)

Link to comment
Share on other sites

 

How would you optimize this code to make it faster? It currently takes almost 3 seconds for whatever reason.....

2610 DISPLAY AT(15,1):" "
2620 RESTORE 3500
2630 FOR I=16 TO MN(C)+15
2640 READ TX$
2650 DISPLAY AT(I,1):TX$;
2660 NEXT I
.
.

3500 DATA 1) HEAL (10 MP)
3510 DATA 2) CURE (15 MP)
3520 DATA 3) LIFE (20 MP)

If there's only three spells then you might as well use a string. Since the strings are all the same length (15 characters) it's nice and simple. This code takes about 0.75 seconds to display:

 

3500 spell$="1) HEAL (10 MP)2) CURE (15 MP)3) LIFE (20 MP)"
3510 for i=0 to 2
3520 display at(I+1,1):seg$(spell$,(i*15)+1,15);
3530 next i

 

Yeah baby. I still got my XB chops :P

Link to comment
Share on other sites

BTW, there is a fourth (forth) spell... I have not named it yet, but it is likely to be named "ALL-HEAL"...

 

The reason it is not listed yet (or implemented) is that it is more costly than anyone can afford yet (MP-wise) The mage will have to be at level 4 or higher to have enough MP to cast it. :)

 

 

That wrenches the 15 char seg., but I love the idea of one string segmented out... I was thinking string array, but your method is pretty slick. :)

 

Since nothing is displayed AFTER the MP cost, maybe we could just pad the first three to have 19 characters (four trailing spaces) :)

Edited by Opry99er
Link to comment
Share on other sites

A string array would have a few advantages - the biggest is garbage collection. Chopping the string up with SEG$ makes a new temporary string every time - once free VRAM is filled, the code will stop and force a garbage collection to clean up the unused memory. With a string array you aren't changing the strings, so there's no temporary string created, so less garbage collection (as well as displaying faster because there's no processing either).

  • Like 1
Link to comment
Share on other sites

That wrenches the 15 char seg., but I love the idea of one string segmented out... I was thinking string array, but your method is pretty slick. :)

 

Since nothing is displayed AFTER the MP cost, maybe we could just pad the first three to have 19 characters (four trailing spaces) :)

Aye. That'll work, however see Yoda's Tursi's post re garbage collection... something to bear in mind. A single string takes up less program space than declaring three strings, and will be a little faster (probably) but it could/will induce a garbage collection once in a while where your program will pause for 1 or 2 seconds.

Link to comment
Share on other sites

Loop starting with a "0"... You damn real programmers with your real programming skills and sh**...

 

It makes much more sense to start from 0. If I started from 1 I'd have to do:

 

3520 display at(I,1):seg$(spell$,((i-1)*15)+1,15);

 

Which seems unneccesarily complex to me!

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...