There's an interesting blog post by Dennis Vorst gone up on the Uniface.info blog, titled Where to put your code. As the title suggests, it's about which places are best for different types of code, based on their content.
There are a number of options; conceptual at the entity or field level, locally at the entity or field level, within the component, a local procedure or a global procedure. All of these have their merits.
I've posted my response, defending the mighty global procedure, but why don't you have a read and add your opinion in the comments?
Summary: Check out this blog post... http://unifaceinfo.com/where-to-put-your-code
Showing posts with label local. Show all posts
Showing posts with label local. Show all posts
Friday, 24 July 2015
Monday, 30 March 2015
Indirection with dollar registers
Indirection in Uniface is a wonderful thing. You can populate a local/component/global variable with a field name, and then use indirection to get the field value of the field that the variable references. You can also use it to set the referenced field to a value, like this...
fld1 = "fld2"
In this example, using the "@" character to indicate indirection, it's the field which is referenced by "fld1" and not "fld1" itself which is updated.
You can even do recursive indirection, which is very cool! Not something I've had a need for myself, but very clever all the same.
However, today I was trying to populate a register the same way, using code something like this...
reg50 = "$50"
In this example, the register was still blank (or whatever the register was before hitting this code).
To be fair, this is clearly stated in the Uniface manuals...
But I still wanted to be able to set registers in an indirect way, so I came up with this alternative...
putitem/id list,"$50","Test"
This works by populating a list with the register and the value, and then uses getlistitems to populate them. The "/id" mode copies items from the associative list into one or more fields, or registers in this case.
For example, you could use a simple for loop to clear out all of the dollar registers...
for count = 1 to 99
This would set each of the 99 dollar registers to blank.
Summary: Indirection works great for fields, but not for registers - however, you can use getlistitems to achieve the same outcome.
fld1 = "fld2"
@fld1 = "Test"
if ( fld2 = "Test" )
;this will be true
endif
In this example, using the "@" character to indicate indirection, it's the field which is referenced by "fld1" and not "fld1" itself which is updated.
You can even do recursive indirection, which is very cool! Not something I've had a need for myself, but very clever all the same.
However, today I was trying to populate a register the same way, using code something like this...
reg50 = "$50"
@reg50 = "Test"
if ( $50 = "Test" )
;this will be false!
endif
In this example, the register was still blank (or whatever the register was before hitting this code).
To be fair, this is clearly stated in the Uniface manuals...
Only fields can be referenced indirectly; the name reached by the indirect reference cannot be a variable. The following example is incorrect because the indirection refers to a general variable rather than to a field:
$1 = "$99"
@$1 = "This string does not go to $99."
But I still wanted to be able to set registers in an indirect way, so I came up with this alternative...
putitem/id list,"$50","Test"
getlistitems/id list
if ( $50 = "Test" )
;this will be true
endif
This works by populating a list with the register and the value, and then uses getlistitems to populate them. The "/id" mode copies items from the associative list into one or more fields, or registers in this case.
For example, you could use a simple for loop to clear out all of the dollar registers...
for count = 1 to 99
putitem/id list,"$%%count%%%",""
endfor
getlistitems/id list
This would set each of the 99 dollar registers to blank.
Summary: Indirection works great for fields, but not for registers - however, you can use getlistitems to achieve the same outcome.
Wednesday, 16 May 2012
Performance of string manipulation - part two
In part one I looked at the different ways of storing a string during string manipulation, and found that using a variable was by far quicker than using a field. In this next part, I'm going to look at the different ways of building up the string. I can think of only two different ways...
- Concatenation (using $concat)
- Indirection (eg. "%%string1%%string2%%%")
So I put these to the test with the following four strings...
"ABCDEFGHIJKLMNOPQRSTUVWXYZ "
"01234567890 "
"abcdefghijklmnopqrstuvwxyz "
"01234567890 "
...holding the value in a local variable and iterating 20,000,000 times...
- Concatenation = 01:03.08, 01:03.71, 01:03.t64 (just over 1 minute)
- Indirection = 01:02.01, 01:01.74, 01:01.98 (just over 1 minute)
The difference is almost negligible, as I had to go to so many iterations before it could be detected. Indirection does pip concatenation to the post though, by a whisker.
I then decided to try building up a larger string, by starting with the first string and adding the other three, then taking that string and adding the other three again, and so on. This time I also used a local variable but iterating only 20,000 times...
- Concatenation = 00:56.41, 00:56.02, 00:56.37 (just under 1 minute)
- Indirection = 00:55.61, 00:56.96, 00:56.92 (just under 1 minute)
Again the difference is pretty negligible, proving that in this case, size really doesn't matter.
Summary: Using concatenation or indirection doesn't really make a difference.
Performance of string manipulation - part one
One thing that every developer fights with (or should!!) is performance. It's ok writing an application that works well for one developer sat messing about on a development server that only he is using, but it is very different when it's thousands of users all hitting the same server, under realistic but heavy load.
One particularly costly task is string manipulation. Building up a string can use a relatively large chunk of memory and take a surprising amount of processor power. So I decided to perform some performance tests to see how this could be improved.
The first test I did was comparing the use of a local variable against a non-database field. I did this test by taking the following string...
" ABCDEFGHIJKLMNOPQRSTUVWXYZ 01234567890 abcdefghijklmnopqrstuvwxyz 01234567890"
...and then using putitem/id with a counter to add this 20,000 times, with the following results...
As you can see, when manipulating a string you should never use a field to hold the string. Having said that, it doesn't seem to make any difference which type of variable you use. I continued testing the different types of variables with 200,000 and 2,000,000 iterations, without seeing the times deviate from each other.
One particularly costly task is string manipulation. Building up a string can use a relatively large chunk of memory and take a surprising amount of processor power. So I decided to perform some performance tests to see how this could be improved.
The first test I did was comparing the use of a local variable against a non-database field. I did this test by taking the following string...
" ABCDEFGHIJKLMNOPQRSTUVWXYZ 01234567890 abcdefghijklmnopqrstuvwxyz 01234567890"
...and then using putitem/id with a counter to add this 20,000 times, with the following results...
- Non-database field = 02:42.14, 02:44.64, 02:43.44 (almost 3 minutes).
- Local variable = 00:00.22, 00:00.23, 00:00.22 (less than 1 second).
- Component variable = 00:00.22, 00:00.22, 00:00.22 (less than 1 second).
- Global variable = 00:00.22, 00:00.22, 00:00.23 (less than 1 second.
As you can see, when manipulating a string you should never use a field to hold the string. Having said that, it doesn't seem to make any difference which type of variable you use. I continued testing the different types of variables with 200,000 and 2,000,000 iterations, without seeing the times deviate from each other.
Summary: Use a variable (any kind of variable) but not a field.
Labels:
component,
field,
global,
local,
manipulation,
memory,
performance,
string,
uniface,
variable
Subscribe to:
Posts (Atom)