|
Author:
DougCMH
|
|
2010-07-30 07.06.17 |
What's really scary is that there are languages out there (real ones, not just
the esoteric ones like INTERCAL) that have some form or other of the COMEFROM
statement. |
|
Author:
CurtisB
|
|
2010-07-29 16.19.18 |
EdMan:
Yep! The worst uses of GOTO I have ever come across are the ones that loop you
back up to a previous part of the code, like yours did, and (I didn't believe it
was even allowed until I saw it once) using GOTO to jump completely out of a
subroutine. |
|
Author:
EdMan
|
|
2010-07-29 15.53.38 |
Curtister...
So it was the "Evil" pgmr.... NOT the "Evil" OpCode ?
LOL |
|
Author:
Basticar
|
|
2010-07-29 15.32.08 |
You know, one of the biggest compliments I ever got on my code, which btw I've
had quite a few over the years ;)
. . . anyhow, I was in the office with my boss and the VP of IT and
Logistics. We were looking at a listing of the main program for a new
application I'd just finished writing when he said with some surprise, "I can
read this!"
Made my week :D |
|
Author:
Basticar
|
|
2010-07-29 15.24.42 |
LOL!
. . . like I said. |
|
Author:
neilrh
|
|
2010-07-29 15.22.59 |
Though you can carry the cost/speed of hardware only so far. Microsoft Word
is a great example of bloatware, that just won't run on systems 2 years older
than the year part of the application name!! |
|
Author:
MrQueue
|
|
2010-07-29 14.59.26 |
Sorry guys---I DID NOT mean to turn this into a GOTO discussion. I was throwing
a little gas on the fire (always a mistake). I did like the Monopoly analogy
though :-)> That would be a good premise for a code experiment for the folks at
improbable.com to work on.
I still work with a couple of guys who place performance high on the list of
what constitutes good code, and it puzzles me quite a bit. When I was a junior
programmer in the early 90's my boss (who to this day I thought was brilliant)
told me, "Don't write coding tricks to eek out performance---hardware will get
faster and cheaper. I'd rather you write something I can quickly understand that
runs a little slow than a slick five-liner that you are trying to get published
in a Computer Science textbook."
Sure enough he was right. Our MRP app was running about 14 hours then. After the
RISC box appeared, the run time had dropped to 2 hours. IF that code is still
running, I would love to know how fast it is now. |
|
Author:
CurtisB
|
|
2010-07-29 14.44.38 |
EdMan:
Which illustrates my point. You had five or six GOTOs that dragged you all over
the program. |
|
Author:
EdMan
|
|
2010-07-29 14.21.50 |
"With all due respect to those who dislike GOTOs, they are not poison. I
myself have not used one in new code since RPGII came out with the IF
statement on the System/36, and only a couple of times since in maintained
code, but there is nothing evil about them. Anyone frightened or shocked by a
single GOTO is overreacting; the evil is in the proliferation of GOTOs, not
the existence of a single one."
SERIOUSLY ????!!!! I will never forget the *Last GOTO I dealt with, it was
about 4 - 5 yrs ago.....
Stmt 2583.00 C N51 GOTO SEARCH_HELL
|
|
|
|
Stmt 4612.00 C SEARCH_HELL TAG
YES... Like 2,100 lines of code away I found the TAG.... Then another took me
to like line 3,300... and so on for about another 4 GOTO's... took me like 5
passes to realize I was being bounced around like a Superball in a small
closet and the door is closed.
|
|
Author:
neilrh
|
|
2010-07-29 14.11.31 |
While something like - DO 2000: x +=1 - works on a PC with a known processor
clock speed (and something that was used on systems like Apple II+). It just
doesn't work on an AS400 where processor speeds are increasing over time (and
we expect our programs written 10 years ago to still be in use today) and
we have job priority and timeslice to contend with. Though I think DLYJOB is
more appropriate than DLTJOB if you want to go into a wait cycle :)
On the subject of processor clock speed, just take a look at some of the old
PC games. A friend of mine loaded Wing Commander (the original game) on his
pentium - it was unplayable as the code was written for a 386 @ 2MHz clock
speed, the pentium running at around 200MHz was blasting through the delay
loops in nanoseconds! |
|
Author:
CurtisB
|
|
2010-07-29 14.07.56 |
Sorry, Bob. I posted before I saw your response. |
|
Author:
CurtisB
|
|
2010-07-29 14.07.08 |
With all due respect to those who dislike GOTOs, they are not poison. I myself
have not used one in new code since RPGII came out with the IF statement on the
System/36, and only a couple of times since in maintained code, but there is
nothing evil about them. Anyone frightened or shocked by a single GOTO is
overreacting; the evil is in the proliferation of GOTOs, not the existence of a
single one.
Now, the COBOL ALTER GOTO combination - THAT is nasty. |
|
Author:
Ringer
|
|
2010-07-29 14.01.47 |
Bobbio, Uh....I think you spaced the (e)
READ(e) myRec;
|
|
Author:
Bob Cozzi
|
|
2010-07-29 13.52.47 |
Boy, oh boy, I agree, let's not only have GOTO-less code, let's have GOTO-less
talk; please!
Who cares what's under the hood, as Neil says? The reason we call them
"high-level languages" is because we don't code machine primitives. You can't
conclude that using a GOTO is faster than a DO or IF on the basis that
everything is converted to a GOTO. Most performance issues, as Hans has told us
time and time again, are at the database I/O level. Fixing something in code
certainly saves runtime, but not by as much as avoiding DB i/o.
We use "IF" instead of CABxx or GOTO because those that follow us, can read it.
not because it runs faster.
Techniques exist for writing code that performs well. Not using lengthy return
values on subprocedures is probably the number one performance issue today--with
a work-around introduced in RPG in v7r1. Second is the use of "B" data-types.
Third is probably the use a huge local variables in subprocedures.
Database I/O performance can be helped using a target data structure on the
Input operation codes.
Here's an allegory, well more of an example, but I've always wanted to use
allegory in a sentence:
dow %status() = 1218;
READ(e) myRec;
if %ERROR();
if %status() = 1218; // Record lock?
do 2000;
x = x + 1;
enddo;
iter;
endif;
enddo;
A classic (albeit not pretty) record-lock detection routine with a retry.
The classic mistake is assuming that DOing a loop 2000 times is the same as
waiting for X seconds (some people think 20, some think 2 seconds). This is
probably the most inefficient way to do this, and yet I see variations it all
the time.
Of course the "best" way is to use the DLYJOB API or MI instruction and wait for
2, 10, 20 whatever, seconds and retry. Otherwise you're using up all the CPU
cycles just trying to "wait" for another job to finish holding a record--and how
is eating up CPU going to help that other job run fast? |
|
Author:
Ringer
|
|
2010-07-29 13.32.55 |
Can we stop with the GOTO talk? Sure compilers might gen one - that's fine - but
a person should not. No one says they are good for coding. Even bad in Monopoly:
GOTO jail, do not pass GO, do not collect $200. Even don't have to code
GOTO's in CL anymore, use ITERATE and LEAVE in the DO loops and RtnSubr in a
subroutine, RETURN from the CL, etc. |
|
Author:
CurtisB
|
|
2010-07-29 13.24.17 |
Neil:
And, of course, using indicators and GOTOs: EQ
X COMP Y 25
N25 GOTO EIF001
* DO SOME STUFF
GOTO EIF002
EIF001 TAG
* DO OTHER STUFF
EIF002 TAG
The problem with GOTO and indicators is not intrinsic; the danger of GOTO and
indicators is that it allows an unrestricted amount of freedom, that programmers
tend to abuse. Anything that involves branching and iteration in RPGIV could be
very easily expressed in RPGII with GOTO, TAG, and one or two indicators. |
|
Author:
Viking
|
|
2010-07-29 13.12.12 |
"I know it's just an opinion I'm asking for, but what percentage of RPG'ers out
there have yet to code a single line of a procedure, regardless of its usage?"
I'll also bet that it's higher than 20%. During interviews recently, I was
surprised how many had not used procedures, service programs, etc. In some
cases they had just been doing the same thing they always had been doing, and
in some other cases they actually were not allowed to use them... |
|
Author:
neilrh
|
|
2010-07-29 12.37.22 |
Under the hood many operations can end up as goto's, especially when you add
compare-and-branch style opcodes. If statements just end up as compare and
branches.
if x = y
do_stuff
else
do_other_stuff
ends up something along the lines of
x cabeq y t0001
goto t0002
t0001 do_stuff
goto t0003
t0002 do_other_stuff
t0003 continue_here
I'm just glad I don't need to look under the hood..... ever! |
|
Author:
MrQueue
|
|
2010-07-29 11.48.59 |
And of course, a compiled subroutine is really a GOTO is it not?
I know it's just an opinion I'm asking for, but what percentage of RPG'ers out
there have yet to code a single line of a procedure, regardless of its usage?
Bob threw a "top 20%" in his insulting rant <g> & made me curious.
I was going to write that I find it hard to believe that it would be over 50%,
but just thinking...at my place of employment, I think just 3 out of 8 have.
That's only 37%. God that is pathetic. |
|
Author:
EdMan
|
|
2010-07-29 09.57.11 |
The only function a GOTO has is that when you see it in the code, You GOTO the
pub and whine at the barkeep |
|
Author:
neilrh
|
|
2010-07-29 09.29.55 |
And all things said - there's little that beats the performance of a GOTO.
And how long have they been outlawed by "structured coding standards"!!
"ah but this <other nationality> are not only stupid, they're ugly too" :) |
|
Author:
CurtisB
|
|
2010-07-29 09.28.34 |
Bob:
On careful rereading, I find that you probably weren't trying to be
condescending.
"Comments are only condescending if people see themselves in those comments and
take it as a personal attack... I wasn't being condescending. I just don't care
if people feel bad when I speak. That's a problem with their upbringing and
their self-confidence, not mine."
I'm not so sure I agree with that argument, though. Suppose I said, "I think
(fill in your disliked nationality) are not ugly, just stupid". The remark would
not be condescending just to members of that nationality who happened to read my
remark and take offense to it. It would be just plain condescending (not to
mention bigoted). If you really care to convince someone of something, you can't
say "If you don't like it, it's your problem, not mine." |
|
Author:
EdMan
|
|
2010-07-29 09.27.12 |
AAAAAaaaahhhhhh yes.... a "Classic" !
"I wasn't being condescending. I just don't care if people feel bad when I
speak."
Amen Brother !
Bottom line ! We are "anal"ysts, developers, programmers, artists, creative
gurus ! We of ALL should be the ones who want to grow and lead the way, the
oones who want to expand their knowledge and feed that hunger. Try new and
(because they are new) exciting things.
I think one of the problem with the Ol' RPG'ers is that no one really
questions them on their approach because it is understood that ofcourse
the "best" possible options are reviewed for what needs to be done. But in
almost all cases... the ol' timers just resort to what they know.... right or
wrong.... and they move forward, because they know it.
Open Thine Eyes ! This is why we are a dying breed.
|
|
Author:
Bob Cozzi
|
|
2010-07-29 08.57.28 |
Comments are only condescending if people see themselves in those comments and
take it as a personal attack. But feeling like one is attacked is a great way to
avoid solving a problem--others often feel compassionate when someone presents
hurt feelings.
I wasn't being condescending. I just don't care if people feel bad when I speak.
That's a problem with their upbringing and their self-confidence, not mine. It
is also why this country continues to be unable to solve any problem "Don't hurt
Johnny's feelings". (Except in politics where the only tactic seems to be
insulting the opponent in an attempt to make yourself appear superior by default.)
If America had this attitude during Pres. Lincoln, we'd still have slavery. "We
don't want to hurt those poor folks feelings, let's not say anything about the
slaves."
If you read my note, I said:
"Subprocedures have more features and capabilities, but subroutines do well in
many situations." Then I went on to say that personally, I don't use subr anymore.
I'll tell you, I've been running my own business since 1983 and have constantly
evolved the technology I use to run it. But today, like 27 years ago, I hate
doing paperwork and try to find the best way to avoid doing it--not the fastest,
not the most efficient, not the cheapest, but a way I can put of doing it as
long as possible. If someone says "Bob, these tax forms were due yesterday" then
I complain about the government--but it is 90% mostly my fault and 10% the
governments--usually. Do cringe, do I coward about paperwork (government tax
forms, payroll filings, income taxes, reports, etc.)? Absolutely I find it to be
the most boring and unnecessary act for any human being on the planet. So when
someone else says "I use Excel, plug in the numbers at the end of each week, and
then when the reports are due, I just print it off." I feel stupid, envious, and
even jealous that they care enough to put that kind of effort into it.
But does it change my old ways of doing it? No, They still work--albeit
problematic year after year, I still continue to do it that way. The people who
tell me there's a better way but your way still works for you even though it
takes a lot longer, are they being condescending?
Time for all of us to get a thicker skin. Life doesn't revolve around us and we
should stop thinking that it does.
|
|
Author:
neilrh
|
|
2010-07-29 08.48.58 |
I don't think I've written a subroutine (except one of them new fangled CL
subroutine thingys) for 3 years now. Being able to replace blocks of move
operations before and after each subroutine, just to be able to vary the
parameters the routine uses, with 1 procedure call containing all the
parameters as local fields... I wonder how many processor cycles I burnt with
code like:
Move field1 parm1
Move field2 parm2
Exsr DoStuff
Move resulta fielda
Move resultb fieldb
Then repeating that block 8 times, where now I can just say (8 times or even
looped into an for...next):
DoStuff(field1: field2: fielda: fieldb) |
|
Author:
CurtisB
|
|
2010-07-29 08.32.54 |
Bob, perhaps you're right about old RPG programmers and subprocedures. But it
may also be that they don't use the new technique because they don't see the
need to. They may not think that subprocedures are better enough to bother with.
If you're careful about your resources, you don't buy a Porsche when a Honda
Civic will do to get you from point A to point B. You will buy the Porsche when
you need to get there very fast. (Unless you are the sort that would get it just
so that other drivers would admire it.)
So older programmers (who may consider themselves careful about their mental
resources) may not learn subprocedures until they see a clear advantage to them,
that they will be able to do something they could not do or found difficult to
do before. Like it or not, subprocedures are more work than subroutines (and I
have used both), at least until you get accustomed to them. Subprocedures will
be used when programmers see the benefit to them. In the meantime, subroutines
work just fine. And a condescending attitude toward those programmers will
likely be the worst way to try to convince them. |
|
Author:
EdMan
|
|
2010-07-29 08.25.44 |
That IS true Daleman... I've done it....
And Uncle Bob.... to tell ya the truth, you are 100% correct, and I have just
basically decided to write "everything" in Procedures(), just to stay current,
but the irony is, is that it now has become job security.... cause as you
said, it new, they don't WANT to learn it, so they basically just throw their
hands up and say... "you wrote it, you support it".... "AAAAaahhhhh.... ok !" |
|
Author:
Bob Cozzi
|
|
2010-07-29 07.51.12 |
If RPG had subprocedures originally, IBM would have never implemented
subroutines. Why, because one is just a modern implementation of the other.
Subprocedures have more features and capabilities, but subroutines do well in many
situations. Personally I don't bother with them, because I try to optimize the
code I write, so its unusual that a subroutine is the better choice (for me).
This isn't a debate about SUBR vs SUBPROC
And as far as I understand there isn't a debate so much as an education cycle.
People know subroutines so that's what they use--but when they need something
different from a program call or more capable than a SUBR call, they learn
subprocedures (plug: I have a 3 DISC Set of self-paced Subprocedure Training).
Subprocs aren't that difficult, they are just new, and RPG programmers (not the
top 20 percent, but most others) in general don't want to take the time to learn
new things. So in stead they rationalize why the way they do it today--the way
they've done it for 20 years--is better than that new fangled way, and that's
fine--it also happens to be the reason there are fewer and fewer jobs for RPG
programmers <g> (specious reasoning, I know). |
|
Author:
DaleB
|
|
2010-07-29 06.53.46 |
Dirty little secret: You can use subroutines inside a subprocedure. Not kidding
- it's perfectly valid, and on occasion makes more sense than calling another
subprocedure. |
|
Author:
Viking
|
|
2010-07-28 16.03.50 |
EdMan says: "I remember a few yrs ago the discussion was Procedures() vs.
Subroutines...."
That discussion is still going on. And usually it's being discussed as if one
has to choose between subroutines and procedures - that they're somehow
mutually exclusive. To me, they're both tools to be used where it makes sense. |
|
Author:
Sarge
|
|
2010-07-28 14.08.05 |
that's okay....i understand and will now speak in colloquialism...
sig p226 - awesome, one size fits all
llama - 1911 frame, .38 super (odd, but a nice point 'n click interface)
as for popcorn, you are right, i prefer the original "shakin' the pan" and was
generally happy with a 80% pop 'n no burn.
-sarge
|
|
Author:
Basticar
|
|
2010-07-28 13.05.52 |
LOL be careful now . . . this is in an honest to goodness "technical thread"
so take your numbers there KgOleMan and put them back in our other stuff so
you won't be shocking the locals ;) |
|
Author:
KgOleMan
|
|
2010-07-28 10.53.25 |
EdMan: I agree performance ain't the issue it used to be. So don't worry, be
happy.
Sarge: The best way to make popcorn is with Orville's or similar, a kettle,
light olive oil, and a real fire source such as a gas range, an Optimus 8R, or
one of the MSR stoves. Then shake it until done. There is a technique to this.
By mistake once I used a special olive oil containing various hot peppers in
it for flavor. The result was known as hotcorn and I have a patent on it. You
had to be either desperate or drunk to eat the stuff but they say at any given
time 18% of the world's population is drunk so I thought why not patent it. I
tell you these cullinary secrets even though in a previous forum you neglected
to mention the Sig 1911 or for a touch more stealth the Seacamp 32. |
|
Author:
exrpg
|
|
2010-07-28 10.09.39 |
Moe: I got this deep fryer on loan from the US Army. It can flash fry a buffalo
in 40 seconds
Homer: 40 secoonnds... but i want it nooow |
|
Author:
Sarge
|
|
2010-07-28 09.33.39 |
once again we show the impatience of mankind. i remember the first commercial
microwaves and how amazed everybody was that they could microwave a bag of
popcorn in 10 minutes. now they get pi$$ed off if it takes them 3
minutes.
of course, i could whip out my trusty 'ol Jiffy Pop and have it cooked in five
minutes and had the fun of interacting by sliding the pan over the GAS burner
and watch the foil unwrap in a spiral as the popped kernels expanded.
-sarge |
|
Author:
EdMan
|
|
2010-07-28 09.20.25 |
Amen Ringster.... I have a guy i work with... his attitude is.."they want
pretty colors ??? I'll give em pretty colors !"
So input fields are yellow, error msgs are red, heading are highlited,
cmd/keys are blue, subfile dislpay flds are green.... you get the picture....
or oil painting if ya like... LOL
And Fish.... Dude you crack me up !!!!!
"Poor response time is one reason I hate the internet. Before I get to the
site and page I am trying to get to I forget what the heck I was looking for
and trying to accomplish."
All I can picture is you standing there with your sunglasses on your head all
pissed off, and asking everyone where the hell are your sunglasses... LOL....
Try bumping up your RAM... or better yet... do a little housekeeping and clean
up all thos downloaded Internet (suppossed to be) temporary files ! |
|
Author:
Ringer
|
|
2010-07-28 08.58.15 |
I pretty much only trim leading spaces when I absolutely know the field in the
database should never have leading spaces, like a part number. If a user enters
a part number in a search field, I %TrimL() it first, before searching.
Fish - regarding the internet, it's true. Users will wait 5, 10, 15 seconds to
get a response back, no problem. But on a green screen, if the wait time is over
a few seconds, it's somehow considered slow. How bout that? |
|
Author:
TFisher
|
|
2010-07-28 08.46.49 |
Edman,
It's always an issue with me. There is nothing I hate worse than having to
wait, even for only 2 or 3 seconds, for a computer to keep up with what I am
trying to accomplish. Poor response time is one reason I hate the internet.
Before I get to the site and page I am trying to get to I forget what the heck
I was looking for and trying to accomplish.
It's true that in most cases we're talking about a difference of milliseconds
for 1 or a few thousand interactions. If you didn’t know before, you know now
that TRIMR is faster than TRIM. When coding, would you purposely use TRIM or
would you use TRIMR with this knowledge? Would it take you any longer to use
TRIMR as opposed to TRIM? Now ask yourself why you made the choice you made
between TRIM and TRIMR.
|
|
Author:
EdMan
|
|
2010-07-28 08.18.50 |
maybe it's me... and of course it probably is.... but is this an issue
anymore... I remember back in the day, performance was a HUGE issue.... but
with the speed of things these days.... does it matter ?
I remember a few yrs ago the discussion was Procedures() vs. Subroutines....
and if I remmeber correctly, Subroutines won for speed, but Procedures() won
for performance.
Of course design is ALWAYS an issue... but in the long run, alot of the ol'
school worries are obsolete along with some of you... LOL.... sorry couldn't
resist
8^) |
|
Author:
TFisher
|
|
2010-07-28 07.54.23 |
There was an old book that use to compare things like CHAIN to SETLL and had
all kinds of benchmarks for various operations. I have not seen anything
published like that over the past several years that covered BIFs and provided
benchmarks for RPG IV.
Yes, TRIM is slower than TRIMR. As a rule, I always use the %TRIMR() built-in
function because we've found that it is faster. It's a no-brainer in most
cases to use the best performing operations and functions, but sometimes you
have to do your own benchmarking and testing to determine which way to go.
This may not always be a valid activity unless the code is being placed in a
loop that will process thousands of records or the program needs extra
attention to obtain a faster response time. A trigger program is another area
where you should focus on using the fastest techniques. |
|
Author:
Ringer
|
|
2010-07-27 15.46.32 |
In general, with RPG strings, performance starts to nose dive around 1000a
lengths. And using CONST and VALUE wisely on the prototype helps too.
http://www.itjungle.com/fhg/fhg062007-story01.html
But typically the bottleneck for a business app, is file I/O. Reduce file I/O
(have prebuilt access paths - PF's/LF's to use) and you speed up the program.
And don't set on *INLR, leave the files open until you want to explicitly close
them. That's huge.
Chris |
|
Author:
neilrh
|
|
2010-07-27 14.32.22 |
The example you've stated probably has more to do with wasting time doing
something that is not needed. Typically a string is left justified and
someone is looking to append extra text to the end of the current content.
Trim performs both a triml and trimr, if you know that your string has no
leading blanks why waste time trying to perform that part of the action.
Another common one is If record exists on file Do something. Many programmers
go straight for the Chain, why bring in the entire record into the input
buffer when you can just Setll and test %equal. |
|
Author:
Basticar
|
|
2010-07-27 14.16.22 |
hmmmm . . . well, I wouldn't worry all that much about the speed of various
opcodes as (imho) that is going to have an infinitesimal, even unmeasurable
effect on the speed of your application.
In our shop our it's the actual application structure as it relates to data
access where our performance concerns center.
|
|
Author:
PvDatSweden
|
|
2010-07-27 14.00.26 |
Hi all.
All too often I read that this opcode is slower than that opcode. Most recently the trim was
considered slower than a trimL or a trimR.
Obviously the knowledge of what opcode has performance issues is something that should be
considered when coding.
However, I've never set my eyes on any paper discussing this. How does one get to know the
performance issues for each opcode?
Regards,
Paulster
(From my android phone) |
|