Author Topic: Arrays  (Read 2245 times)

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
Arrays
« Reply #30 on: July 03, 2011, 12:09:40 pm »


               This Code is ripped out of a larger content
but your "il" struct should really have been a struct containing name and il.i0 should have been itemlist.itemproperty (or something similar that tell us what it contain)

same goes for all the il.i3 and so on. You can't simply not understand the code if you don't know what each index hold for int value. ie makes the code harder to read.

which i have pointed out. the code itself isn't inefficent.    

if (nAddCount) {

       sAddedDescription = "=====\\nEnchantment Quantity: " + GetEnchantmentQuantity(nAddCount) + " (+" +
                                IntToString(nAddCount) + ")\\n" + C_LIGHT_GREEN + "Added:\\n";
       for (ss = GetFirstSubString(sAdded, " "); ss.first != ""; ss = GetFirstSubString(ss.rest, " ")) {

           il = GetIntList(ss.first, ",");
           if (GetIsItemPropertyStacking(il.i0, il.i1)) {

               if (il.i0 == ITEM_PROPERTY_ARCANE_SPELL_FAILURE){

                   //do special asf encoding
                   if (il.i3 < 10) {
                       nX = 10-il.i3;//encode 'asf good 1-10)
                       AddLocalInt(oItem, "RIPStack_84_0", nX);
                   }
                   else {//fake subtype for bad spell fail prop
                       nX = il.i3-9;//encode 'asf bad 1-10)
                       AddLocalInt(oItem, "RIPStack_84_1", nX);
                  }
               }
               else
                   AddLocalInt(oItem, "RIPStack_"+IntToString(il.i0)+"_"+IntToString(il.i1), il.i3);

           } else {


               sAssemble = IntToString(il.i0)+","+IntToString(il.i1)+","
                           +IntToString(il.i2)+","+IntToString(il.i3)+","
                           +IntToString(il.i4)+","+IntToString(il.i5);

               sTempString = GetLocalString(oItem, "TempPropString");
               if (sTempString != "")
                   sTempString += " ";

               sTempString += sAssemble;
               SetLocalString(oItem, "TempPropString", sTempString);
           }

           if (GetIsItemPropertyImmunity(il.i0))
               il.i3 = GetCostValueFromPercentImmune(il.i3);

           sAddedDescription += C_LIGHT_GREEN + "  " + GetItemPropertyInfoDirect(il.i0, il.i1, il.i2, il.i3, il.i4, il.i5) + "\\n";
       }
   }
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Arrays
« Reply #31 on: July 03, 2011, 12:17:12 pm »


               

FunkySwerve wrote...

Seriously, how would you do the IntList functionality, without all those ebil structs?

Funky

just note I have a pseudo-list that is an array where if you erase one element, all others move (is this even correct definition i dont know)

I did it this way: i have a aplhabet constant and im using a single character as a member identification, then I use two local variables, one for a list's all members and second for a member value

like this:

string LIST_name abcd
int LIST_name_a 1
int LIST_name_b 2
int LIST_name_c 3
int LIST_name_d 4

then i can loop all members and erase them, so if i delete member c then i just delete int LIST_name_c and then substract "c" char from members list. It has a downside of only 250+- possible members and a not very efficient search in a list but otherwise its very useable. Since the way it works I allowed this to store not just int but any other engine structure and so on...

If anyone likes this I can share ofc.
               
               

               


                     Modifié par ShaDoOoW, 03 juillet 2011 - 11:17 .
                     
                  


            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
Arrays
« Reply #32 on: July 03, 2011, 12:22:50 pm »


               the second example is similar but also contain some encoding you could improve. in this case you the number of supported cases isn't large so the gain isn't wouldn't be noticable. but if you start adding alot of custom itemproperties and subtypes you could gain of using direct mapped encoding.

you should work with pseudo arrays as you do with streams and other buffert memory. you can use encoding to ensure a cleaner code or faster code.

if you don't understand what i have told you it's more likely because you can't handle critism on your code. and want me to post code so you can attempt to strike back. my code wouldn't be that diffrent from the snipped code but i would have added converter functions aswell. which there seem to be in your also but you haven't posted them.
               
               

               
            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
Arrays
« Reply #33 on: July 03, 2011, 12:36:29 pm »


               

ShaDoOoW wrote...

FunkySwerve wrote...

Seriously, how would you do the IntList functionality, without all those ebil structs?

Funky

just note I have a pseudo-list that is an array where if you erase one element, all others move (is this even correct definition i dont know)

I did it this way: i have a aplhabet constant and im using a single character as a member identification, then I use two local variables, one for a list's all members and second for a member value

like this:

string LIST_name abcd
int LIST_name_a 1
int LIST_name_b 2
int LIST_name_c 3
int LIST_name_d 4

then i can loop all members and erase them, so if i delete member c then i just delete int LIST_name_c and then substract "c" char from members list. It has a downside of only 250+- possible members and a not very efficient search in a list but otherwise its very useable. Since the way it works I allowed this to store not just int but any other engine structure and so on...

If anyone likes this I can share ofc.


This is a way of encode the data. but it's a bit unclear. is abcd independent entries or is one entry containing data a,b,c,d. depending on which it is you should handle it accordingly. if it's an entry you normally want the list to close itself and move the entry. ie index doesn't matter. you always process them from the beginning to the end.

but it all depend on the properties of the data you want to store, which approach you should take. if you want to store a hugh sparse matrix you will gain by adding a encoding that identify the data. rather then having it full with empty entries.
               
               

               
            

Legacy_the.gray.fox

  • Full Member
  • ***
  • Posts: 214
  • Karma: +0/-0
Arrays
« Reply #34 on: July 03, 2011, 05:55:45 pm »


               Are we talking of programming?
Or are we talking of scripting?
It is the all important detail you seem to be forgetting.
Maybe you just lost focus. It happens.

The only way of coding-for-speed, in nwscript, is to write your code so that it uses as less instructions as is possible.
<< The fastest code is that which does not run >>
Self-explanatory, I am sure.

High Level? Low Level? All meaningless.
Using switches to do this? Then it is bad because the user will likely use another switch to do that...?
Did you know that a switch are if-else in disguise in nwscript?
It has the constraints of the switch (they managed to bug that too, btw) but always if-else they are.

Nwscript is a script language. Interpreted by a Virtual Machine.
High Level by design, and Slow by definition.
Every single instruction in your NSS shall evaluate to a whole function call in the VM. Complete with pushing and popping of args on the stack then cleanup according to the calling convention. These things are not for free. They happen continually and do eat up cycles.
There is no such thing as "atomic" in this context, for you do not run directly on the metal -- but on an abstract software layer that is far away from it (and I bet the interpreter itself is far from optimized for speed).

So what is all this fuss about writing faster code?
The only way to go fast in nwscript is to write less.
At the end of the day it will matter the amount of instructions within the NCS file (and in case of loops, the less iterations the better)
Lesser = Faster.
That is a direct measure of how fast your code is.
Everything else is chit-chat.

You may invoke the pow() to calculate a power of 2... Or you may do a left shift directly.
In nwscript both things will set in motion a slow function call.
The speed gain of a cheap left shift will be absorbed. And unless you wrap them in a tight loop, you are not going to measure any sensible boost by using either method.

In this context, you see, writing code that is easy to read and maintain is the best move anybody can do.
Especially if we consider that most users here do not chew the language comfortably.

Finally, take a look here:

int a = 205761315;
a *= 6;

int b = 205761315;
     b <<= 1;
b += b <<  1;

Unless you use an optimizing compiler, the b way is going to outspeed the a way anyday. Right, on the CPU.
But in the nwscript VM the a way is going to be about 4 times as fast as the b way. (***)

In nwscript only the instructions count does matter.
The more data manipulation and calculus you do "outside" of the script layer, the faster you go.

[edit]
I forgot the conclusion. So much writing and too little re-reading.

(***) = With the uber CPU we got today hardly you are going to appreciate a speed difference unless it is something remarkable. What is the ponit of squeezing your brain to write uber code, when someone else can write something quasi-as-fast and in 1/10th the time you did your? Off putting thought, to be ure, but that is the reality we are facing with modern hardware. Might be better to employ one's expertise to write code that is easier to read and maintain (comments also help in that snse, of course).


-fox
               
               

               


                     Modifié par the.gray.fox, 03 juillet 2011 - 05:13 .
                     
                  


            

Legacy_TrekSL

  • Newbie
  • *
  • Posts: 35
  • Karma: +0/-0
Arrays
« Reply #35 on: July 03, 2011, 07:12:20 pm »


               Going to go away and absorb page 1 (I suspect page 2 here may be more of an argument and not necessary to me!) Be right back!!!!
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #36 on: July 04, 2011, 12:58:05 am »


               

TrekSL wrote...

Going to go away and absorb page 1 (I suspect page 2 here may be more of an argument and not necessary to me!) Be right back!!!!

Page 2 is mostly spam. If you can answer my questions I'll happily set you up with something.

Funky
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #37 on: July 04, 2011, 01:50:21 am »


               

CID-78 wrote...

unwilling would be the word. I am experienced enough to ignore young cooky (usually student) who think they are best until proven otherwise. Why should a waste a hour on you?

It's not so much wasting an hour on me as it is backing up your own critique. Social scientists have a rule in critical theory - purely negative critiques are a waste of time if you're unable to demonstrate a better way. Even by the end of this page, you haven't. All you've done is toss out one self-contradictory complaint after another.

if i would spend time to prove how to script Apllication X or script Y. I would never finish my own projects and they would exploit me for resources.

Perhaps that's true, but the same thing could be said about you shooting your mouth off in the first place. Unless you support it with something, you're just spouting hot air.

But i can comment your code or the authors code, because your spending alot of time defending some one else work.

I'm not defending anything yet, because you have yet to raise a reasonable objection to the code. I'm simply pointing out your arrogance in calling the code 'awful', given your failure to comprehend the examples I posted. Your mouth is writing checks your coding skills can't cash. And you want to accuse ME of being the cocky young student? Lol. I'm just asking you, if you're going to run around offering highly negative unsolicited critiques of code, to back up those critiques with something, ANYTHING.

/*CID-78: Fixed sized array struct with ten entries, it can obviously only handle arrays with size 1-10,
it kind of kill the meaning of a pseudo array, which really should act as a vector.
ie you shouldn't need to care how many entries it has. */

That isn't the pseudoarry function, GetFirstSubstring is. Have you even read the include I posted? IntList is a utility function for quickly schlepping a concatenated string into individual ints so they can be easily referenced. But then, I already explained all of that. If you can't see the practical utility of that, it's not a failure in the code.

/*CID-78: Fixed sized array struct with 15 entries, same as above but like above your locking yourself down to a type and size*/

Yes, we ARE locking ourselves down to a type and size when we do that. That's how structs work. It is not that downside for which we do it, but the upside of being able to refer to struct members in array-like fashion. Given that YOU were the one complaining how the functions should be more C-like, it's more than a little ironic that you fail to grasp the reason for these two functions.

string GetStringSubString (string sString, int nIndex, string sSep=" ") {
int nSep, nStart = 0, nSkip = GetStringLength(sSep); /*CID-78: be happy that nwscript set all variables to zero otherwise would nSep be unknown here*/

No kidding. If only acaos had known that nwscript auto-initializes declared variables and taken advantage of it to keep code shorter, instead of doing it by accident and lucking into working code...a couple thousand times. Wonders never cease. And yes, we all know this isn't C. Are you really so desperate to find fault with this code?

/*CID-78 the two following functions are what i thought was awfull*/

Yes, I'm well aware. What I'm asking you to do is explain WHY you think it's awful. All you do here is talk some more about structs being fixed. Oh, hey, by the way: water is wet.

CID-78 wrote...

but your "il" struct should really have been a struct containing name and il.i0 should have been itemlist.itemproperty (or something similar that tell us what it contain)

same goes for all the il.i3 and so on. You can't simply not understand the code if you don't know what each index hold for int value. ie makes the code harder to read.

GAAAAAAAH. AGAIN, from the guy who was babbling about wanting things more C-Like. You've got to be putting me on. Does this look EVEN REMOTELY FAMILIAR TO YOU?:


int il[10];
il[0] = '44';
il[1] = '256';
il[2] = '25';

That is how our InList function would hold a 25% fire immunty effect, IF IT WERE WRITTEN IN C. Are you SERIOUSLY NOT GETTING THIS YET? The ENTIRE POINT of the functions you referred to as 'awful' is to be able to treat things in more C-like fashion, by referring to 'array' members with numbers, and NOT declared variables or lengthy names. They are PUPOSEFULLY kept short to keep the code clean, yet another thing you were claiming to care about. They only have an i before them because nwscript wouldn't compile them otherwise. They only run to 10 numbers because that's all that we need for our (dozens of) uses for this struct, and because we want to avoid needless declarations. Should we need more, it'd take all of a second to expand the struct. Larger, more general arrays are handled with GetFirstSubString, as should be obvious.

which i have pointed out. the code itself isn't inefficent.

...
Congrats, you've convinced me. You don't have the foggiest clue what there is to dislike about these functions. First it was that they were inefficient - now, apparently not, after I challenged you to produce more efficient ones. You said you disliked the structs. Then you said it wasn't the structs, it was the switches (even more inane, as fox points out). You say you want C-like code but don't understand how the code IS C-like. You say you want clean code, but advocate for lengthy nomenclature where the code has been specifically set up to avoid the need for it. And you make incorrect guesses about the use of the functions when I've explained it repeatedly and pasted examples showing those guesses to be completely wrong.

My theory? You shot your mouth off without thinking, and have been hastily backpeddling ever since. Kindly stop littering the thread with this nonsense, and let the people who understand what's going on here help the OP.

Funky
               
               

               


                     Modifié par FunkySwerve, 04 juillet 2011 - 12:52 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #38 on: July 04, 2011, 01:56:58 am »


               

the.gray.fox wrote...
(***) = With the uber CPU we got today hardly you are going to appreciate a speed difference unless it is something remarkable. What is the ponit of squeezing your brain to write uber code, when someone else can write something quasi-as-fast and in 1/10th the time you did your? Off putting thought, to be ure, but that is the reality we are facing with modern hardware. Might be better to employ one's expertise to write code that is easier to read and maintain (comments also help in that snse, of course).

Thank you fox, this is PRECISELY the point I was making about learning to value other things besides speed on the last page. Very well demonstrated, too.

Funky
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Arrays
« Reply #39 on: July 04, 2011, 03:49:51 am »


               

FunkySwerve wrote...

the.gray.fox wrote...
(***) = With the uber CPU we got today hardly you are going to appreciate a speed difference unless it is something remarkable. What is the ponit of squeezing your brain to write uber code, when someone else can write something quasi-as-fast and in 1/10th the time you did your? Off putting thought, to be ure, but that is the reality we are facing with modern hardware. Might be better to employ one's expertise to write code that is easier to read and maintain (comments also help in that snse, of course).

Thank you fox, this is PRECISELY the point I was making about learning to value other things besides speed on the last page. Very well demonstrated, too.

Funky

well funky, nothing against you, your scripting is always experienced and professional but is not going the Fox's post rather against your script? Since the speed difference is unremarkable, in the end it matter rather if the script is readable and easy to understand which none of your scripts are... Structs are very hard for beginners and I would bet the OP didn't understand your arrays function at all.
               
               

               
            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
Arrays
« Reply #40 on: July 04, 2011, 07:04:43 am »


               Gray fox also got it. In this case less is better. ie your script would work fine without structs and be easier to read and faster to execute and yes structs lock your down to a type and that's why they should go away in almost all cases.

if you use structs you make one for each specific case with good names and load/save it without a switch.

sure it might be more code (several struct that need function for load/save) but less code that execute. and easier code to read.

I will end this discussion now. if you can't get it by now it's futile, your blind to the argument. so lets focus on the OP's needs.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #41 on: July 04, 2011, 01:08:28 pm »


               

ShaDoOoW wrote...
well funky, nothing against you, your scripting is always experienced and professional but is not going the Fox's post rather against your script? Since the speed difference is unremarkable, in the end it matter rather if the script is readable and easy to understand which none of your scripts are... Structs are very hard for beginners and I would bet the OP didn't understand your arrays function at all.

Not at all, no. If you'll recall I pointed out that the (slightly) slower speed of the IntList setup was a tradeoff for added utility - being able to treat things in more C-like array fashion. Our scripts are eminently readable, when you look at the whole - you're seeing a tiny chunk of a larger script in the examples I post. I was not posting the examples for end-use, merely to illustrate the different roles of the more general array function and the more specialized IntList. The entire scriptset is thousands of lines of code, in all of which the same 6 numbers - itemproperty, subtype, costtable, costtable value, paramtable, paramtable value - are used over and over again. IntList simply provides a compact way of dealing with those values, which the people working with that script on our server are intimately acquainted (and comments in the code indicate the values).

As for readability and ease of understanding, I don't really see much difference between our code include and, say, bioware's. I also don't really see structs as all that complex - they're covered pretty early on in coding texts. If, by contrast, you're referring to the examples, you're talking about seeing a tiny chunk of a highly complex system - no one is going to grasp it easily, but that's not because it relies on IntList. In the end, it's also going to depend on a coder's skill - functions designed to emulate C arrays are naturally going to appeal more to those with experience with it. If your objection is that these functions were made by an experienced coder for use by experienced coders - sure, they were, and they don't comment every line as a result. The include I posted for him was simple enough, though.

In the end it's always going to come down to a coder's personal preference in how they balance various concerns like readability, efficiency, and modularity. The more experience you have, the easier some things come, and the more apparent the value of modularity becomes. I spent a LOT of time writing redundant code before I twigged to that. Modulatiy, for example, generally increases complexity and (arguably) readability, decreases efficiency, and saves time in writing. If you're just reading through the code, you'll get the general idea more qucikly. You just wind up looking through a few more includes before you get the total picture, should you need to modify it, to make sure your edits aren't going to have unintended consequences. Naturally, the more practice you have at doing that, the more comfortable you're going to be with it. Likewise, with enough experience, you can do things that those with less experience find confusing, but which save you a great deal of time and code. If only other people with like degrees of experience need to work with that code, it's all upside. Though, to be honest, I still wish acaos would do a little more commenting than he does. '<img'>

Funky
               
               

               


                     Modifié par FunkySwerve, 04 juillet 2011 - 12:33 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #42 on: July 04, 2011, 01:13:09 pm »


               

CID-78 wrote...

Gray fox also got it. In this case less is better. ie your script would work fine without structs and be easier to read and faster to execute and yes structs lock your down to a type and that's why they should go away in almost all cases.

Fox was posting pointing out the error of your thinking. Read his post again. I love that you've changed gears YET AGAIN and are now complaining about readability, after yourself having orginally claimed to care about nothing but efficiency - a goal that is at loggerheads with readability and other concerns, as Fox (and I) pointed out.

if you use structs you make one for each specific case with good names and load/save it without a switch.

This is just wrong. Structs are just another datatype you can customize to your needs. You can make them as generalized or as specific as you like. You really don't have much experience with high-level languages, do you?

I will end this discussion now. if you can't get it by now it's futile, your blind to the argument. so lets focus on the OP's needs.

It's admittedly hard to see an argument that changes with the wind. '<img'> If you're going to stop wasting my time with your nonsense, so much the better.

Funky
               
               

               


                     Modifié par FunkySwerve, 04 juillet 2011 - 12:17 .
                     
                  


            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
Arrays
« Reply #43 on: July 04, 2011, 06:40:42 pm »


               I have alot of experience with both high and low level programming.

actually you can read grey.fox as we both would be wrong. it all boil down to personal style. i prefer fast clean code. sometime i end up with a few functions extra but the number of function executed will allways be small. which yield a fast code. no matter how inefficent the virtual engine is. And it handles structs in a really inefficent way so you know.

Itemproperties  can code can easily takeup alot of codespace. When i constructed my CEMIS system. (over a hundred custom itemproperties along with the standard ones), the code was still very fast, the space it needed was for the lists of properties it needed to understand. and with it i didn't need to write custom script for each magic item. Did I need a Int struct list? No and i have never have had a need for such struct.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Arrays
« Reply #44 on: July 04, 2011, 07:26:40 pm »


               

CID-78 wrote...

I have alot of experience with both high and low level programming.

actually you can read grey.fox as we both would be wrong. it all boil down to personal style.

You're the only one who advocated the untenable position that only efficiency mattered at the outset of this thread:

CID-78 wrote...

let just say we have diffrent opinions on what's the best approach. I allways go for speed.

His post was aimed pretty directly at pointing out the problem with that thinking.

As for your item property setup, my guess is that you wouldn't have found IntList nearly as useful, because you didn't use ItemPropertyDirect and nwnx_structs. Without them, you have to apply item props piecemeal using parameters, instead of building them all using the same 6 numbers. It makes working with the props infinitely easier, and allows much cleaner database tables for them.

Funky