My 2 cents: According to a recent 4D blog entry, using the new object notation option will speed up your objects significantly:
"Good news, now you have a mean to get rid of all those OB Get <http://doc.4d.com/4Dv16R4/4D/16-R4/OB-Get.301-3318080.en.html> and OB SET <http://doc.4d.com/4Dv16R4/4D/16-R4/OB-SET.301-3318074.en.html> in your code! And you know what? The code execution is *10 times faster with the object notation* compared to OB Get <http://doc.4d.com/4Dv16R4/4D/16-R4/OB-Get.301-3318080.en.html>/OB SET <http://doc.4d.com/4Dv16R4/4D/16-R4/OB-SET.301-3318074.en.html> usage!" See http://blog.4d.com/another-way-of-coding-object-notation/? You'll need to be using v16r4 I believe. But even if you're not on v16 yet, it's worth keeping in mind. Pat On 21 July 2017 at 09:22, Nigel Greenlee via 4D_Tech <[email protected]> wrote: > Global Variables. > > Regardless of the relative merits of Arrays vs Object. I would like to > relay my dislike in general of Global variables. I have been working with > 4D since before the concept existed-since 4D V2(Globals came in with V3). > Yes i am one of the old boys. > > Back then we did not have multiple processes and when V3 arrived we were > all amazed and in awe of the ability to have multiple processes and I think > we all went mad for interprocess(global) variables.(i think we all had > singing dancing palettes on the screen doing fancy things to update > themselves from other processes). > > Now if we were working in Javascript the concept of a global variable > would very much be considered something to be avoided like the plague. > Global variables are extremely useful but also extremely prone to problems, > and over the past couple of years-any javascript tutorial tells you to try > and avoid them, in 4D I have really cut down on my use of them. > > In my opinion a global variable should in general only be used for two > things. > 1) You want to set a value(or group of values) and through the life of the > programme they do not change once set(so here you are using them like a > constant) > 2) You want to maintain an array that will be written to by multiple > processes. > > With point 2 you must protect the arrays with semaphores so only one > process alters the arrays at any one time-and often where these are used > there might be other ways to do it. > > I have just this week been dealing with 2 different structures where the > liberal use of interprocess arrays has lead to problems. Problems that do > not show up in testing and probably show that that the way the routines has > been used has changed over time. In both cases-different > companies-different programmers-different stuff an error shows up just > occasionally. In one of those systems discussion with the client shows that > the usage of interprocess variables has caused ‘strange’ unexplained > un-investigated things to happen where process A is changing the contents > of <>Variable just at the point when process B is about to send the > contents of <>Variable that process B had set to a document (‘sometimes we > get a situation where the same order document is created twice’!!)..and > they have just restarted the machine to get rid of the problem in the > past(a practice that means you think the problem is 4D not the way the code > is written). > > Simply protecting the handling so only one process at a time can modify > the interprocess variables and arrays would have avoided all this. I > suspect the original programmer never intended the functionality to be > running in multiple processes at the same time and used interprocess arrays > to (I think) make it easier to display the data on a form that is in a > different process. Beyond the idea of a form in a different process i don’t > see any purpose in the arrays in this case being interprocess-they are > being constantly changed and as such should at best have been process > arrays, In fact in a modern context(this was written way before that) where > we have been able to pass pointers to local variables since 4D V11(??-maybe > it was before that) I would generally argue that programming using locals > is much better-and that could be local objects or local arrays. These > really show that an interprocess array was used for convenience where it > was not really needed and changes to code did not include a proper > assessment of the impact-just because you can do something and it works > once does not mean it is tested or fit for purpose. > > In most of my code over the past few years I have moved so far away from > <> variables that if i have more than a few-maybe a variable holding the > user name or something like that which does not change(and even there I use > a function ..UTIL_GetUser(“Name”)..). I have even moved largely away from > process variables and arguable could move further from them by not using > variable names on screen objects. Convincing clients to let me change their > code and actually changing it is not easy-in one case about the changes to > the code are on a live system running uncompiled and this morning i am > going to be attempting to apply a knife to this code. > > > Most code i write now is ‘self contained’ -I attempt to set all values > used in the method is passed in to the code -either as parameters or an > object or a pointer to something so that i end up with something more like > a javascript function. Myreturn:=MyMethod(something;something;something). > Using this style of coding means i am far more likely to get an error if > there is one EVERY TIME rather than a head scratching randomly appearing > one and my code does not rely on the perceived value of a variable. > > Consider > > If(<>SOmething=1) > //do something > end if > > as soon as you have more than process where <>something is set you run the > risk that at some point process A will set <>something to 1 and before it > tests if <>something =1 process b changes <>something to 0 so you put a > semaphore to stutter your code.. > > if you write > > if(something=1) > //do something > end if > > //now process B can do whatever it likes with something and process A will > not be affected but you still run the risk that somewhere you call this > function before you have C_Longint(something) and something is not > initialised. Even if ‘something’ should be initialised to the value of > '<>something' this should be done at the start of the process and never use > '<>something’ in the code. When i find code that uses '<>something' or > ‘something'i have to look to see where something is set what changes it and > work out everything about it. > > if you write > C_LONGINT($something) > if(Count parameters>=1) > $something:=$1 > end if > > if($something=1) > //do something > end if > > You have code that is not dependent on the value of a variable it is only > dependent on a value being passed in, and that might mean that the calling > method also can use a local. This means i only need to see where my code is > called and check that it is passing a relevent value to the code-much > easier to track down a fault. > > This is a simple ‘one step’ example but I frequently see code chains like > this. > > Methoda sets var-calls-method b-calls-method c-calls method d-and method d > has if(var set in method a), and that is really where this chain of > handling becomes a mess-we have method and the variable is set 3/4 levels > up or worse set at startup in the code. > > If you pass an object the concept can become of course much more flexible, > and slowly i am trying to adopt an object passing approach > > C_OBJECT($Something) > If(Count parameters>=1) > $Something:=$1 > end if > > if($Something.setting=1) > //do something > end if > > Becomes much easier to read(no unpacking the object here). > > After all its used extensively in javascript where passing json normal and > with V16 now using dotted notation for getting at object item is a big > encourement to utilize this(yet to test that out myself). > > > > Are other people taking this approach to the use of variables. How easy > are you finding it retro-fitting it to existing code? > > > Nigel Greenleee > > > > > > > On 18 Jul 2017, at 16:29, Chip Scheide via 4D_Tech <[email protected]> > wrote: > > > > Long ago - and I am pretty sure the code has been lost to time - > > in v2.2.3 (I think) I wrote code to do binary searching on a selection, > > as at that time Search Selection (the old command name) was sequential, > > but sorting the selection was indexed. > > > > Even with the overhead of managing the pointers, and stepping through > > records to find all matching records in the selection, as memory > > serves, it was faster (interpretedly) to use the binary search on a > > selection size of beginning at 6-8 records. > > > > For those who care, an outline of a binary search (on records in > > selection) > > The following was written off the stop of my head, in the email editor, > > BUT it gets to the basics of a binary search on a selection in 4D. > > > > - get size of selection ($Selection_Size). > > - make sure it is sorted on the field you want to search on. > > > > repeat > > $Current_record:= int($Selection_Size/2) > > > > repeat > > goto selected record([table];$Current_record) > > case of > > :($Current_record>=$Selection_Size) or ($Current_record<=1) > > $Not_Found:=true > > :([table]field = Value) // found it create collection of > > matching records > > add to set([table];"Matching") > > $previous:=$Current_record > > $Next:=$Current_record > > > > repeat > > $previous:= previous-1 > > goto selected record([table];$previous) > > > > if ([table]field = Value) // found it create collection of > > matching records > > add to set([table];"Matching") > > else > > $previous:=0 > > end if > > until($previous=0) > > > > repeat > > $$Next:= $Next+1 > > goto selected record([table];$Next) > > > > if ([table]field = Value) // found it create collection of > > matching records > > add to set([table];"Matching") > > else > > $Next:=Selection_Size > > end if > > until($Next= Selection_Size) > > $Mo_More_Matches = true > > :([table]field > Value) // Not found current record value > > > search value > > $Current_record:=int((1+$Current_record)/2) > > :([table]field < Value) // Not found current record value < > > search value > > $Current_record:=int((Selection_Size+1+$Current_record)/2) > > end case > > until ($Not_Found)) or ($No_More_Mathes) > > > > At this point the set "Matching" contains all records matching the > > criteria, or nothing. > > > > On Tue, 18 Jul 2017 22:16:18 +1000, David Adams via 4D_Tech wrote: > >> > >> And, lest anyone forget, you can use binary search logic on sorted > >> selections with GOTO SELECTED RECORD. Why not? > > --------------- > > Gas is for washing parts > > Alcohol is for drinkin' > > Nitromethane is for racing > > ********************************************************************** > > 4D Internet Users Group (4D iNUG) > > FAQ: http://lists.4d.com/faqnug.html > > Archive: http://lists.4d.com/archives.html > > Options: http://lists.4d.com/mailman/options/4d_tech > > Unsub: mailto:[email protected] > > ********************************************************************** > > ********************************************************************** > 4D Internet Users Group (4D iNUG) > FAQ: http://lists.4d.com/faqnug.html > Archive: http://lists.4d.com/archives.html > Options: http://lists.4d.com/mailman/options/4d_tech > Unsub: mailto:[email protected] > ********************************************************************** > -- ************************************************* CatBase - Top Dog in Data Publishing tel: +44 (0) 207 118 7889 w: http://www.catbase.com skype: pat.bensky ************************************************* ********************************************************************** 4D Internet Users Group (4D iNUG) FAQ: http://lists.4d.com/faqnug.html Archive: http://lists.4d.com/archives.html Options: http://lists.4d.com/mailman/options/4d_tech Unsub: mailto:[email protected] **********************************************************************

