home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-03 | 74.0 KB | 1,211 lines |
-
-
-
-
- //////// // // //
- // // /// // //
- // // //// // //
- //////// // // // //
- // // //// //
- // // /// //
- // // // ///////
-
-
-
-
-
- Pascal NewsLetter
- Issue #4
- July, 1990
-
-
- Editor: Pete Davis
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Programmer's Forum BBS is the home of
- PNL. It can be reached in Washington, DC at
- (202)966-3647. Information is available
- through the following locations:
-
- FidoNet: Pete Davis@1:109/138
- Genie: P.DAVIS5
- BitNet: HJ647C@GWUVM & UE356C@GWUVM
- InterNet: HJ647C@GWUVM.GWU.EDU
- or UE356C@GWUVM.GWU.EDU
- or Pete.Davis@f138.n109.z1.fidonet.org
-
- Table of Contents
- Introduction .................................. 3 (P.D.)
- Letters to the Editor ......................... 5 (****)
- Binary Trees For Sorting ...................... 7 (R.M.)
- Putting the Spurs to Pascal ................... 15 (J.R.)
- For Beginners ................................. 22 (B.G.)
- Review of TechnoJock's Turbo Toolkit .......... 27 (J.A.)
- Review of Turbo Pascal-The Complete Reference . 29 (P.D.)
- Key to author names:
- P.D. -> Pete Davis - Senior editor and writer
- B.G. -> Bob Gowans - Staff writer
- J.R. -> Jan-Erik Rosinowski - Contributing writer
- R.M. -> Robert Mashlan - Contributing writer
- J.A. -> John A. Abele - Contributing writer
- 3
- Introduction
- Well, PNL003 finally got off, so now I guess it's about time
- to get started on issue #4. I was so pleased with PNL003 that I
- was worried I might break my arm patting myself on the back. It
- was a good issue, though, and I was very pleased. I hope issue 4,
- and all the issues to follow for that matter, are just as good or
- better.
- I received a wonderful letter the other day from a reader
- who said he got a subscription to the Cobb Group newsletter on
- Turbo Pascal. He said that he and a friend compared it to PNL and
- said that they preferred mine. It's this kind of support that
- really makes me want to keep writing this.
- I hope that people will keep up the contributions. They've
- been a fantastic support for me. Without them, I don't know if
- I'd be able to go on with this. There have already been a lot
- sent that I couldn't have written myself and I think that makes
- it more interesting for the regular readers.
- Because of the time consuming nature of writing the
- NewsLetter, I'm afraid I might be stuck with only putting out one
- issue every two months or so. I doubt it would really be much
- longer than that. I am looking into getting some more permanent
- writers who I can count on to write an article for every issue
- and maybe even pitch in on the editing. Right now, Bob Gowans is
- the only person who has had the time to be able to contribute on
- a regular basis. PNL is still young, though, and growth can be
- expected, but it might slow down a bit. Since the first issue,
- the PNL has grown very quickly, but things seem to be steadying
- out a bit.
- Well, in this issue we've got an article on Binary Trees, a
- very powerful data structure, which once understood, can be very
- easy to implement. I had already planned on doing an article on
- Binary Trees, but got a submission from a reader on them. Since
- Robert's article covers the basics of Binary trees, I decided I
- would take a bit more complex route and discuss the AVL tree
- balancing algorithm in a future issue.
- I've also had a reader, John Abele, who sent in a terrific
- review of the TechnoJock's Turbo Toolkit. I am doing a review of
- Turbo Pascal - The Complete Reference by Stephen K. O'Brien.
- These will be only the start of reviews that will be done on
- books, toolkits, and software related to Pascal.
- I think the star of this issue is going to be the PROFILER
- and accompanying article that are in this issue. I've used to
- profiler a bit myself and have found it very useful. I hope you
- like it. Originally the article was written in German and thanks
- to the tremendous effort of one of my BBS users, Howard Sanner, I
- 4
- was able to get the article translated to English. Howard
- suggested, and I agreed, that it was best to leave the article
- using some of the expressions that are distinctly German, in the
- article, instead of trying to write something in English that
- wouldn't convey the meaning the author was trying to get across.
- I hope this poses no problems.
- All-in-all, I think this issue came out very well, and
- again, let me thank all those who contributed and hopefully I can
- get other readers to contribute also.
- 5
- Letters to the Editor
- From uunet!GWUVM.BITNET!HJ647C
- From: uunet!CUNYVM.CUNY.EDU!CDCKAB%EMUVM1.BITNET (Karl Brendel)
- To: Pete Davis <HJ647C@GWUVM.UCAR.EDU>
- Date: Fri, 27 Jul 1990 13:04 EDT
- Pete--
- I've just read the second issue of PNL (the first one I've seen).
- Thanks for this work!
- Not wanting to be critical of article--being critical is so
- much easier than writing--but Craig Thurber's references to the
- $L compiler directive is completely wrong, to the point that you
- really need to issue a correction in your next issue.
- Reference _Turbo Pascal Reference Guide_ for 5.0 or 5.5, pp
- 434-5 and 437-8 in my copy. {$L filename} is the "link object
- file" directive. {$L- or {$L+ are the "local symbol information"
- directives. Craig indicates that {$L filename} is the local
- symbol information directive and that it is ignored if debug
- information is off ({$D-}) (PNL002, pg 17). He shows an external
- file linked as {$L+ HELLO.OBJ}. This will not work. It appears
- that Craig doesn't understand how to use the link directive.
- It appears to me that neither he nor you tried to compile or
- use his code. As printed, the program "Hello" will neither
- compile nor run. One of the compile errors is from a typo (a
- problem every publication has), but the other is from Craig's
- misuse of {$L+. I urge you to require your writers to compile and
- run every single line of code they send you, and to repeat the
- compilation and running yourself before publication.
- Best wishes. I'm looking forward to PNL003.
- Karl Brendel
- Centers for Disease Control
- Epidemiology Program Office
- Atlanta, GA
- Karl,
- You bring up a valid point. To be honest, not all of the
- code that goes into the articles themselves has really been
- checked by me to see if it works. I do read through the articles
- and try to get an idea of the competency of the writer and see if
- the ideas are valid. I must admit that from time to time things
- will slip by, but from now on, actual code going into the
- articles will be tested.
- It appears Craig had made a small mistake and I thank you
- for pointing it out to the readers. I am afraid that this will
- 6
- probably happen again, at some point and hope that in the future
- readers will respond, as you have to make the corrections that
- slip by us here at PNL.
- _Pete Davis
- Editor
- 7
- Binary Trees for Sorting
- By Robert Mashlan
- A binary tree is a useful sorting device in structured
- programming. It is a quick and easy way to maintain data in a
- sorted order.
- A binary tree is composed of units called 'nodes'. These
- nodes are linked together in a special way to form a tree. A
- tree requires the use of pointers, and each node of the tree must
- be allocated dynamically. If you don't quite understand the
- concept of a pointer, don't worry, just read on.
- A pointer is nothing more than a variable that holds the
- address of another variable. Pointers are used to access dynamic
- variables, that is, variables that you can create or destroy at
- will. Besides possessing this flexibility, you may hold more
- data with dynamic variables than you could by using global and/or
- local variables.
- In a program, the construction of pointers is
- straightforward. In the type declaration of a program consider
- the declaration
- Type
- stringptr = ^string;
- or in English, 'Let stringptr denote that all things of this type
- point to things of type string!'. In the declaration there is a
- caret '^' which simply means 'pointer to'. It takes on a
- slightly different meaning when used in the actual code.
- Now we need to declare an instance of a pointer so that it can be
- used:
- Var
- sp : stringptr;
- What we have done is to declare an instance of a variable
- that points to a string. This variable doesn't take much space;
- pointer in Turbo Pascal it is 4 bytes.
- Now we need to allocate storage for a string on the heap:
- begin
- New(sp);
- What we have done here is told a set of routines called the
- 'Heap Manager' that we need some space for a string. If there
- are 255 bytes in a row, the Heap manager complies and sets the
- value of sp to the address of the space that it gave us for the
- string. This space will be protected from being given to other
- 8
- requests for space until the space is reclaimed with dispose.
- Now that we have allocated space for it, we can now use it. The
- caret '^' comes into play again as it is needed to dereference a
- pointer. This means 'refer to the thing I point at'.
- sp^ := 'I am a dynamic string!';
- writeln(sp^);
- Now when we no longer need the string, we can get rid of it,
- possibly reusing the space that it occupied. This is done with
- the dispose function:
- dispose(sp);
- end.
- After using dispose, the value that sp had is now no longer
- valid. That means don't read it, don't change it, don't use it
- for anything unless you reallocate space for it with the new
- procedure. A pointer with an invalid value that is being used
- often causes really mean bugs. It may write to almost anywhere
- in memory, like the next instruction to be executed, the IDE, the
- operating system, etc. The problem is that these kind of
- problems may not show up until much later, such as when you exit
- your program and run another.
- You should also try not to lose track of your pointers, or
- you'll get a 'memory leak' that wastes space that could be used
- for other purposes. Whenever a pointer goes out of scope always
- dispose the space it points at.
- A pointer can also have the special value nil. This simply
- means that the pointer points at nothing. It can be assigned to
- any pointer.
- Ok, now on to the forest:
- First a graphical demonstration of creating a binary tree:
- Say we have these pieces of data and we want to sort them in
- alphabetical order:
- G, B, A, H, I, E, J, F, C, D
- The first letter G, we will denote as the root of our tree:
- G
- / \
- The node that G is in points to other nodes, which are
- currently pointing at nothing.
- 9
- Now we add the next letter B. To add it, we use the algorithm:
- 1) Start at the root node
- 2) if the node is empty then
- place the data here
- else
- if the data is greater than the data at the node then
- go to the right node
- else
- go to the left node
- go to step 2
- By using this algorithm, we now have
- G
- / \
- B
- ( Unused datum: A, H, I, E, J, F, C, D )
- The next step would be:
- G
- / \
- B
- /
- A
- to
- G
- / \
- B H
- / \
- A I
- to
- G
- / \
- B H
- / \ \
- A E I
- to
- G
- / \
- B H
- / \ \
- A E I
- \
- J
- 10
- to
- G
- / \
- B H
- / \ \
- A E I
- \ \
- F J
- to
- G
- / \
- B H
- / \ \
- A E I
- \ \
- F J
- to
- G
- / \
- B H
- / \ \
- A E I
- / \ \
- C F J
- to
- G
- / \
- B H
- / \ \
- A E I
- / \ \
- C F J
- \
- D
- Now we have a strange looking upside down tree that seems to
- have no reason to it. To use this tree, we must transverse it.
- This is the name of a special algorithm that we use to 'travel'
- through the tree so that it comes out in sorted order. The
- traversal algorithm:
- 1) start at the root node
- 2) do procedure 2
- 3) end
- 4) if node is not empty then
- do this procedure with the left node
- process the data at this node
- do this procedure for the right node
- 11
- Using this algorithm with the tree we start at the root node. The instructions tell us to go left, so we go to B. Next we
- go to A. Since there is no left node to A, we process A, or in
- this case, write it down. We now return to B and print it. The
- instructions say go right, so we end up at E. Now we go left to
- the C node and print it. Mentally traversing the rest of this
- tree is left as an exercise to the reader.
- The traversing algorithm is called recursive, that is, the
- algorithm calls itself.
- If you have a good mental picture of what a tree is, read on
- for a demonstration of implementing it in Pascal.
- ----------------------
- Program TreeSort;
- Const
- MaxStr = 255; { The maximum length of strings to be used }
- Type
- Str = string[MaxStr]; { Our string type to be used }
- { We now declare a node record and pointer type: }
- nodeptr = ^node;
- node = record
- data : str;
- left, right : nodeptr;
- end; { record }
- { The node record type has three fields. The first field data,
- is used to store a string, the things we are to sort. The left
- and right fields contain pointers to other nodes. When these
- nodes aren't pointing at other nodes, they will be assigned the
- value nil. }
- { Next we must have a root to our tree: }
- Var
- root : nodeptr;
- { Root is not actually the root, but a pointer that will point to
- the root node of our tree. }
- InData : str;
- { This variable will be used by the main block of this program }
- 12
- Function NewNode( var newdata : str ) : nodeptr;
- { The purpose of this function is to allocate and and initialize
- space for a node. The newdata parameter is the string that
- will be placed into the Node's data field. newdata is passed
- by reference to reduce stack usage. }
- var
- result : nodeptr; { the value to be returned }
- begin
- New(result); { allocate space for the new node }
- with result^ do
- begin
- left := nil; { set these pointers to point at nothing }
- right := nil;
- data := newdata; { store the data in the node }
- end; {with}
- NewNode := result;
- end; {Function NewNode}
- Procedure Add( var newdata : str );
- { This procedure is an implementation of the 'word' algorithm
- used
- to add data to the graphical tree. The string that is passed
- as a parameter will be stored in the tree. }
- var
- chase : nodeptr; { this pointer is used for }
- { moving through the tree }
- done : boolean; { the done flag }
- Function Compare( var a,b : str ) : boolean;
- { This nested function tells the outer procedure the order
- that the data is to be sorted. It is to return TRUE is a is
- to go to the left of b. In this case we are comparing
- strings in alphabetical order with no regard to case }
- var
- i, limit : integer;
- begin
- if length(a) < length(b) then { limit is to be the maximum}
- limit := length(a) { number of times to loop, }
- else { In this case, the length }
- limit := length(b); { of the shortest string. }
- i := 1;
- while ( i <= limit ) and ( Upcase(a[i]) = UpCase(b[i]) ) do
- i := succ(i); { Increment i }
- { at this point either a mismatch occured or the strings
- 13
- Matched up to the length of the shortest string }
- if UpCase(a[i])=UpCase(b[i]) then
- Compare := length(a) > length(b)
- { longer strings go after shorter ones }
- else
- Compare := UpCase(a[i]) > UpCase(b[i]);
- end; {Function Add.Compare}
- begin
- if root = nil then
- root := NewNode(newdata) { gotta start somewhere }
- else
- begin
- done := false;
- chase := root; { start at root }
- repeat
- with chase^ do
- begin
- if Compare( data, NewData ) then {go to the left}
- if left = nil then
- begin {put the data here}
- left := NewNode(newdata);
- done := true;
- end
- else
- chase := left { move on to the left node }
- else { go to the right }
- if right = nil then
- begin { put the data here }
- right := NewNode(newdata);
- done := true;
- end
- else
- chase := right; { move on to the right node }
- end; {with}
- until done;
- end; {else root=nil}
- end; {Procedure Add}
- Procedure Transverse( np : nodeptr );
- { This is the transversal procedure to the tree. It calls the
- nested function Process in sorted order. Note that this
- procedure is recursive. }
- Procedure Process;
- begin
- writeln(Output, np^.data);{write data to standard output}
- end; {Procedure Transverse.Process}
- begin
- 14
- if np <> nil then
- with np^ do
- begin
- Transverse(left);
- Process;
- Transverse(right);
- end; {with}
- end; {Procedure Transverse}
- {Pretty short, huh?}
- begin {Program TreeSort}
- { This program is a filter, that is, it takes input from
- standard input, sorts it, and send it to standard output.
- It works like the sort filter you get with MS-DOS }
- root := nil; { initialize Root }
- while( not eof(Input) ) do { read all the input datum }
- begin
- readln(Input,InData);
- Add(InData);
- end;
- Transverse(root);
- { transverse the tree and write out the datum }
- end. {Program TreeSort}
- ----------------------
- To use this program, create an ascii text file of strings to
- sort. Type in the command:
- >treesort < data.dat
- and the sorted output will be displayed.
- Binary trees are useful for many sorting applications, and
- are fairly quick. There are a few disadvantages to binary trees,
- namely the recursive nature of the transversal algorithm. In a
- case where the incoming data is nearly or already sorted. The
- tree will appear to look like a linked list, or a very long
- chain. This will cause the transversal algorithm to call itself
- many times and possibly cause a stack overflow error.
- That's it. If you have in questions or comments, you may ask
- them in the FidoNet International Pascal Echo or via FidoNet
- NetMail to Robert Mashlan @ 1:147/34.33
- 15
- PUTTING THE SPURS TO PASCAL
- by Jan-Erik Rosinowski
- Does it un-nerve you when, with increasing development time,
- your program runs progressively slower? Editors that cannot keep
- up with the cursor? Databases that seem to be stored on cassette
- tape? Though the complexity of the problem can cause bewildering
- frustration, it is constructive to use a profiler at this point.
- It will expose the time-consuming procedures, so that nothing
- will stand in the way of subsequent significant optimization of
- the program. Such a profiler for Turbo Pascal v. 4 and 5 programs
- is described below.
- There are two approaches to program optimization, the
- theoretical and the practical. They will both be briefly
- sketched.
- PROGRAM OPTIMIZATION IN THEORY AND PRACTICE
-
- The theorist uses the following method: using a simply
- canonical approach, he searches for the theoretically lower
- limits of the best algorithm. The time to formulate and verify an
- algorithm is limited only by the author's maximum writing
- speed--at the latest, after a midnight snack of pizza he is in
- the know. For him, the implementation of the algorithm is almost
- secondary: This would require him to write a small program, and
- in such a manner could many free hours and years pass!
- In contrast, the graceless practitioner: He writes his
- database program using a BASIC interpreter. Before thinking two
- minutes about the program, he has written 100 lines. After a
- hundred test runs that help him in the "verification" of his
- program, he has a bug free version. He often thinks the
- following: The program's done. Only he can no longer coordinate
- the long coffee break his computer's run time has forced upon
- him. After a compiler doesn't help him, he decides to re-write
- the program in assembler. For quick access to his data, he once
- again uses a linear, sequential search.
- AND HOW ONE DOES IT RIGHT
- Though both examples were exaggerated, it is clear that
- neither approach is workable. Clever optimization of a program
- comes after a careful analysis of the problem and costs. Then one
- must next analyze the kernel functions of the planned program. In
- a database program, these would be, for example, functions to
- insert, update, delete, search, and index data records. Along
- with the expected quantity and format of data and operations, one
- 16
- also selects appropriate data structures. Thus one chooses here
- suitable algorithms, for example, linear searching, B-trees, or
- hashing. An estimation of the expected overall complexity, the
- provision of resources (time, money, tools), and taste/experience
- will quickly determine the high or low-level programming language
- to be used.
- After solving the general complexity of the problem, one
- should, in the first, analytical phase, in no case underestimate
- the time taken up by operating system functions. In many programs
- they claim a large part of the total run time. Bypassing DOS and
- BIOS calls will definitely yield a copious increase in speed, at
- the cost of many gray hairs when porting the program to another
- system. Routines with extreme requirements, for example, a screen
- handling package for a text program, will need to be purchased.
- AND THEN!
- After choosing appropriate algorithms, data structures, and
- programming languages, places ripe for optimization can be
- quickly identified. There are, of course, many sloppily-written
- small routines that are called unexpectedly often. If these are
- optimized first, relatively small optimizations will yield a big
- improvement in run time. Routines should be re-written in
- assembler or, for example, a bubble sort replaced with a
- quicksort.
- The amount of improvement to be gained from using a profiler
- is inversely proportional to the amount of thought put into the
- original design. In other words, the greater effort put into a
- statement, analysis, and evaluation of the problem, the fewer the
- opportunities for improvement. The true art of efficient
- programming thus lies in appropriate decisions in the analysis
- and coding phase.
- PRACTICE
- With the profiler's help, you can quickly do away with the
- worst time wasters in a Turbo Pascal program. The program package
- consists of a preprocessor (PROFILER.PAS) as well as the analysis
- unit, PROFILE.PAS. The work of the preprocessor is to imbed a
- call to "PBegin" and PEnd" at the beginning and end of each
- function, respectively. (See listings 4 and 5.) When the program
- runs, these procedures capture timing statistics. Both the format
- and use of upper and lower case in the source code are
- unimportant. Include files and source code of available units are
- both processed. In addition, the Pascal ugliness of "Record,"
- "Case," and "End" (in contrast to Modula-2 or single logic only
- 17
- "End") is digested without complaint.
- The programs were developed under Turbo Pascal 5.0. Only
- changes to a few CONST declarations and case selectors are needed
- to adapt it to the previous version. The assembler part,
- PROTIMER.ASM, was assembled with MASM.
- WILLY GO!
- The preprocessor "PROFILER" runs only from the DOS command
- line. The first parameter expected is that of the name of the
- module to be analyzed. This can be either one unit or the whole
- program. Modules linked in with "uses" or include directives are
- each processed. If one wants to omit a module (e.g., one that
- exclusively reads the keyboard via the BIOS), one can name the
- file to be excluded after the /X: option. Names without extension
- are interpreted as ".PAS," and this applies to all source files
- (thus units to be excluded with "/X: XYZ.TPU" will cause an
- error).
- In order not to inflate the profiler's size, it assumes that
- the program to be processed has no syntax errors. This isn't
- really a restriction, since the profiler is intended to be used
- to put the finishing touches on the program. The profiler will
- also not be of help to people who, as already mentioned above,
- plan their programs in the coding phase. The module to be
- profiled must always have either a "Program" or "Unit"
- identifier.
- THE BIG RENAMING
- So that one can't work with source code the profiler has
- processed (the time checking calls will not be found in the
- finished program), the files to be processed are renamed. Thus
- the first and last letters of the extension are exchanged (".PAS"
- becomes ".SAP"). This can nevertheless lead to problems should a
- program be run through the profiler again, as well as with files
- like, for example, "INCLUDE.010." The latter must be renamed to
- something reasonable. The PAS-SAP collision is best avoided with
- a batch file that will copy the identically named ".SAP" files
- over the ".PAS" files. The latter may then be deleted.
- INTERPRETING THE RUN TIME PROFILE
- After one has compiled the profiler-processed program and
- tested it adequately, the unit PROFILE will generate the run time
- analysis [PROGRAM/UNIT NAME].PRF from the file [PROGRAM/UNIT
- 18
- NAME].PR$ produced by the profiler. In the first column is the
- procedure name, in the second the number of calls, and in the
- third column the run time in milliseconds. In contrast to the
- notion of run time in reference (1), here it means only the run
- time of the procedure itself. It does not include that of the
- subprocedures it calls. This considerably simplifies usage, so
- that one can directly see the true time a procedure consumes
- (figure 1). By means of the DOS SORT program one can generate a
- list by run time, so that one can immediately find the slow parts
- of a large program.
- The definition of run time in reference (1), in contrast to
- that given here, always shows 100% for the main program's run
- time, which is true in few cases.
- A marginal note: Anyone who tests the entire program being
- analyzed with the profiler and gets unexpected results must
- remember that the time the profiling unit itself takes can be
- compensated for by setting the variable "adjusttimer" to a more
- precise value. The true run time of the program is small compared
- to that of the stopped.
- Should one wish to test the program isolated in diverse
- situations, one can delete the uninteresting procedures from the
- ".PR$" file with a text editor. (Delete whole lines.) This will
- greatly reduce the confusion of paper, since the profile unit
- will only emit a run time profile for procedures in the ".PR$"
- file.
- Should the program terminate before the "End." statement,
- there will nevertheless be a run time analysis. In this case the
- profiler will issue a corresponding warning. This can happen, for
- example, if the profiler is used to analyze itself, since the
- main program terminates with a halt statement. The run time of
- the "open" procedure will be approximate.
- One small piece of bad news: External procedures (in
- assembler or C, for example) cannot be directly analyzed. If this
- is desired, one must enclose them in an outer procedure. This
- presupposes changes to the external procedures (public names); an
- extension of the profiler in this regard would be excessively
- complex.
- INTERNALS
- The profiler consists of two kernel procedures: one, the
- recursive function "prep_module" that inserts the calls to the
- profiler. It is recursive, since it calls itself in analyzing
- uses and include modules. This serves to simplify the file
- management, since thus Turbo Pascal gets stuck with the dirty
- 19
- work. The second important procedure, "getsymbol," supplies
- "prep_module" with tokens and handles include modules. That the
- rest of allocated storage isn't released should not trouble you;
- DOS also takes no notice of it, since the management is handled
- internally by Turbo Pascal.
- The most important function of the unit PROFILE is
- "readtimer." It makes possible accurate timing at microsecond
- intervals; it thus has substantially greater resolution than the
- BIOS or DOS timers. In spite of what the manuals say, the DOS
- timer cannot resolve time finer than five milliseconds. The more
- precise results of the "readtimer" procedure are also not
- surprising, when we consider the fact that the BIOS timer, which
- is also used by DOS, is incremented whenever the timer used in
- the "readtimer" procedure counts down to zero. Timer zero of the
- 8253 chip acts as time keeper. It is critical in this connection
- to coordinate with the 8259 interrupt controller; under the worst
- circumstances it can falsify the measurements "catastrophically"
- (by five milliseconds). This can happen if the timer has been
- latched and an interrupt is triggered between the time the
- counter value is stored and the interrupt request register is
- read. An extremely low counter value indicates that request flag
- has been set. Since this is nevertheless influenced by the timer-
- independent CPU frequency, an adjustment of the constant "corr"
- in PROTIMER.ASM is needed. Also, the DRAM refresh and installed
- cache programs (DOS buffers, FASTOPEN, VCache, etc.) falsify the
- measurement not inconsiderably. For these reasons it is important
- to keep the timer resolution under 1/100000 seconds and not to
- put the unit PROFILE into an overlay. The constant "fracs" in
- PROFILE.PAS determines the number of decimal digits to which the
- run time in milliseconds will be displayed.
- The unit PROFILE will normally be the first unit entered
- once the program is started and the last left (via an Exitproc).
- The counter is installed, and the correction value needed to
- account for calls to "PBegin" and "Pend" calculated, via calls to
- the initialization blocks. The local stack as well as the storage
- space "procstore" are statically declared, and the constants
- "stacksize" and "maxprocedures" must be adjusted. Dynamic memory
- allocation in the profiler might cause errors, since the program
- to be analyzed could also manage its storage by means of
- MARK/RELEASE or also DISPOSE.
- Listing 5 is presented as an example of capturing timing
- information. Time measurement begins with PBegin (1). Since
- nothing is on the stack yet, PBegin stores only the number of the
- active procedure (1) as well as the system time. The call to
- PBegin (2) in the procedure "a" causes the time used in procedure
- 1 (stored time-elapsed time- correction value) to be saved in
- "procedure[1].time." Again the number of the active procedure (2)
- and the system time are pushed on the stack. PEnd performs the
- analog: it closes off the active procedure and then pops its
- 20
- record off the stack. Since the system time is once again read,
- the second call to PEnd can determine the run time of the main
- program correctly.
- LIMITATIONS OF USE
- Use of the profiler can lead to problems in the following
- circumstances:
- 1. As mentioned above, extra steps are needed
- to analyze procedures written in other languages.
- They must be given different public names so that
- one can write enclosing procedures with their
- original names. If only a few modules are involved,
- it may be quicker to change the names in the Pascal
- source.
- 2. Programs or PCs that themselves make use of
- timer zero can cause minor irritations and
- influence the unit PROFILE, respectively. In this
- case, the procedure READTIMER (PROTIMER.ASM) must
- be changed.
- 3. The run time analysis is only procedural.
- The time taken by DOS and run time library calls
- must also be accounted for. One would be well
- advised, for example, to redefine the file
- functions in their own unit. "READ" and "WRITE"
- statements unfortunately often evade this method.
- In individual, truly critical cases, one can extend
- the ".PR$" file with a pseudo-procedure after the
- last line. It will then carry all the PBegin and
- PEnd calls associated with the "READ" and "WRITE"
- statements.
- 4. Time critical procedures, as, for example,
- a serial port handler, will take longer to run, and
- thus the profiler may interfere with their
- operation. For this reason, interrupt procedures
- are automatically excluded from analysis. One must
- either delete the PBegin and PEnd statements from
- time critical procedures or put them in units or
- include modules that are excluded with the /X
- directive from analysis.
- 5. "Inline" procedures cannot be analyzed with
- any tricks. This corresponds to their character.
- The shortest machine programs execute in a fraction
- of a microsecond. Anyone who would like to analyze
- such a time critical section should perhaps
- 21
- consider coding it completely in assembler.
- With these hurdles crossed, nothing stands in the way of
- analyzing your critical source code. One should, however, always
- put readability and correctness of a program before its speed,
- otherwise one can program the same as in C or BASIC.
-
- References
-
- 1. Profilgewinn, c't 5/89.
- 2. Interrupts auf Reihe, 5/86.
- 3. Die PC-Referenz
-
-
- Figures
- 1. PROTEST.PRF: This is the result of the analysis
- of PROTEST with the unit PROFILE.
-
- Listings
-
- 1. PROFILER.PAS: This program links calls into
- Turbo Pascal 4/5 compatible source code that
- make possible an analysis accurate to the
- microsecond.
- 2. PROFILE.PAS: This unit measures the procedure
- run times and generates a run time profile from
- them.
- 3. PROTIMER.ASM: This procedure can read the timer
- with microsecond precision.
- 4. PROTEST.SAP: The program to be analyzed
- appeared thus before the application of the
- profiler.
- 5. PROTEST.PAS: The profiler has here performed
- all of its work.
- 22
- For Beginners
- By Bob Gowans
- In the last issue of PNL the beginners column discussed the
- use of the Pascal assignment operator ( := ) to assign values to
- variables. We were concerned mainly with operations on the
- variable data type integer, a simple Pascal data type, and were
- made aware of other Pascal data types such as char, Boolean and
- real. In this issue we will further increase our knowledge of
- variable operations by designing a simple program and
- implementing our design as a Pascal program. In particular we
- will be paying close attention to correct initialization of
- variables and input and output.
- Later you will be presented with a simple problem and from
- this we will devise a design to solve this problem but first lets
- discuss the technique by which we may solve the problem. First we
- must make sure that we fully understand the problem. How?... By
- asking relevant questions so that we are made fully aware of all
- the details of the problem. For example, if we were asked to
- update a catalogue of books we might ask How many books are
- there? Are they to be ordered? How are they to be ordered, by
- title or by author? You can probably think of many more questions
- to ask until you are fully satisfied that you thoroughly
- understand the problem.
- Next we would start to devise a solution keeping in mind
- that our ultimate aim is to implement the solution to the problem
- by making use of a computer. Devising an efficient solution when
- using a computer is something that comes about as you gain
- experience of your computer system's capabilities, its advantages
- and disadvantages.
- One of the best methods of problem solving is by a process
- known as TOP-DOWN DESIGN. This involves simplifying the problem
- into a series of broad terms and then adding more detail as you
- look at each term. For example, the solution to the problem of
- how to update a bank account is given as follows:
- (a) Give a broad outline
- 1. read in transactions
- 2. bring the accounts up to date
- 3. print out a list of transactions
- (b) Start to refine the broad outline
- 1.1 read in credits
- 1.2 read in debits
- 2.1 calculate the total credits
- 2.2 calculate the total debits
- 2.3 calculate the new balance
- 3.1 print out credits
- 3.2 print out debits
- 23
- 3.3 print out new balance
- Each step would then be further refined until we are at a
- position to implement the solution.
- Implementing the solution would result in the construction
- of a Pascal program from our refined design. When the program is
- entered into the computer and successfully executed then the
- associated problem is solved. Whenever a solution is to be
- implemented there are three important stages to consider :
- 1) Data input or reading in information to the program.
- 2) Processing instructions - the main body of the
- program.
- 3) Results or output. For example, to the printer or
- screen or some other output device.
- After having completed the implementation of your design
- successfully, always go back over what you have done, ask
- yourself if you managed to solve the problem to your satisfaction
- and does the solution work for all cases that could arise?
- Finally it is vital that you make a written record of what you
- have done. Say for example several months later, you want to
- amend the program. If you have clear, concise documentation
- covering all aspects of your design and solution then the process
- of amendment should be made much less painful.
- Now lets take a simple problem and using the above, process
- solutions ready for implementation in Pascal.
- Problem 1 : We are going back to the bank again. This time the
- bank manager has asked us to devise a program that will assist
- his customers. He wants an interactive program that will prompt
- the user for the balance in his deposit account and then print
- out, to the computer screen, the new balance with interest at the
- end of the first interest period.
- First lets ask some questions :
- 1) What is the current rate of interest?
- 2) Over what period is the interest calculated?
- 3) How is the new balance to be calculated?
- 4) What will happen if there is a withdrawal from the account?
- Ask as many questions as you like until you are fully
- satisfied that you understand the problem. For the purpose of
- this problem the bank manager supplies you with the following
- answers :
- 1) Interest is paid annually at 13%
- 2) The period of interest is quarterly ie 3 months
- 3) The new balance is the current deposit plus the accumulated
- interest.
- 24
- 4) The account is new and no withdrawals are allowed
- We are now in a position to construct a broad design of the
- intended program.
- 1. set values of variables ( or initialize variables )
- 2. calculate the new balance at the end of the quarter
- 3. write out the result
- The broad outline is easy and understandable and although
- this is a much simplified case the same principles apply when
- dealing with more complex design. Let us continue by refining the
- broad outline to a more specific list of instructions.
- 1.1 initialize interest rate
- 1.2 initialize interest period
- 1.3 initialize deposit
- 2.1 calculate interest
- 2.2 set balance to deposit + interest
- 3.1 write out 'New balance is ', balance
- The design is now at a stage where it could be implemented
- as a Pascal program, however there is nothing to stop you from
- further refining the design if you think it necessary. At this
- point it would be beneficial to stop and reflect over our design
- for a moment or two. In our design there are three statements
- asking us to initialize certain data, if a data table is
- constructed we can make clear the data structures and what we
- intend to do with them.
- Identifier Description Type
- ========== =========== ====
- deposit amount of money in account real variable
- rate interest rate per year real variable
- interest calculated interest real variable
- quarter period over which the
- interest is calculated real variable
- balance total money in the account
- after first quarter real variable
- The design has introduced a new data type REAL. A real data
- type is defined as 'positive and negative numbers that include
- decimal points'. Our real variables must be initialized, or given
- a starting value before they can appear in an expression in the
- program. It is true to say that many Pascal systems will
- automatically initialize variables to zero, however it is not
- good programming practice to presume this and it is much better
- if you ensure that all variables used in the program are properly
- initialized.
- Using the data table we can now write the declarations part
- of the program ( the part where all the variables are declared ).
- 25
- var
- deposit : real;
- rate : real;
- quarter : real;
- interest : real;
- balance : real;
- Note this could also be written as
- var
- deposit,rate,quarter,interest,balance : real;
- Initializing the variables in Pascal is as follows, using the
- statements from lines 1.1, 1.2 and 1.3 of our design
- rate := 0.13; { 13% as a decimal fraction }
- quarter := 0.25; { 1/4 of a year expressed as a decimal }
- readln(deposit);
- The first two lines make use of the Pascal assignment
- operator ( := ) which we discussed in the last issue of PNL. The
- readln statement is new to us and merits a brief discussion. The
- use of the readln statement results in assigning a value to a
- variable from an external source ie from outside the program. As
- our program specified an interactive design we expect the user to
- input some information, a passing of information must take place
- between the user and the computer. The program will temporarily
- halt when it encounters the readln statement, expecting some data
- to be input. It is vital that interactive programs communicate
- while they run so that the user will know when he is required to
- input the data. The way to do this is to use a program prompt. It
- is also important that interactive prompts ask make clear their
- purpose. Lets add an interactive prompt to our program ensuring
- it comes before the readln statement.
- write('Please enter your deposit here > ');
- Steps 2.1 and 2.2 of our design are fairly straight forward
- and are implemented as follows :
- interest := deposit*rate*quarter;
- balance := deposit + interest;
- Finally step1 requires the output to the screen for the
- information of the user.
- writeln('The new balance is ',balance:10:2);
- The writeln statement informs the user of his balance plus
- interest and provides a neat format. The :10 after the variable
- balance allows a field width of 10 characters for the output and
- the :2 ensures the output is rounded to two decimal places. Try
- 26
- the program without these output controls and note the results.
- The whole program can now be put together;
- program new_balance;
- { calculates balance on deposit at a rate of 13 % over 3
- months }
- var
- deposit : real; { entered by user }
- rate : real; { current rate of interest}
- quarter : real; { a period of three months }
- interest : real; { calculated interest on deposit }
- balance : real; { the new balance }
- begin
- rate := 0.13;
- quarter := 0.25;
- write('Please enter your deposit here > ');
- readln(deposit);
- interest := deposit*rate*quarter;
- balance := deposit + interest;
- writeln('New balance is ',balance:10:2)
- end.
- In conclusion top down design is a method for designing a
- solution to a problem that is going to be implemented on a
- computer. If you look at the design, it is understandable to a
- non programming person as it conveys a broad outline of the
- problem. With further levels of refinement and a data table you
- are ready to implement your design. Show your final coded program
- to the same non programming person and the chances are that he
- will have no idea what it is about. By designing your programs
- before coding them, you will have a much more clear understanding
- of exactly what your program does and will find that coding soon
- becomes routine and effortless.
- Error : In PNL # 3 the following line should be inserted in the
- program add_up
- after male := 100; :- total := male + female;
- I hope that this did not distract from the understanding of the
- program.
- 27
- TechnoJock's Turbo Toolkit
- A Review
- by John A. Abele
- Those of us who are serious/professional programmers need to
- know about those rare individuals who have become programmer's
- programmers. These folks write the toolkits and other utilities
- that save the rest of us from a lot of tedious "grunt work" in
- our programming.
- TechnoJock's Turbo Toolkit is a well done series of 12 Turbo
- Pascal units that is worthy of your consideration. It is
- published by TechnoJock Software, Inc. of Houston, Texas.
- Briefly, the 12 units are as follows: 1) fast screen
- updating, 2) windows and boxes, 3) user input training, 4)
- directory display and retrieval, 5) keyboard manipulation and
- reading, 6) dynamic list management (this one is a real winner),
- 7) menu display, 8) nested menuing, 9) pull down (Lotus-like)
- menuing, 10) data type reading (like reading only integers from
- the keyboard), 11) string manipulating (some good functions found
- here), and 12) things that don't fit anywhere else such as date
- manipulating, file information, on-screen clock and some printer
- testers.
- You'll find some razzle-dazzle procedures in this toolkit,
- such as sliding part of a screen in from the left or windows that
- appear to explode from the center.
- What I appreciate about this toolkit is its overall concern
- with what the screen looks like. We are all aware that some of
- the best programs never get used because the screen is sloppy or
- un-inviting to the user. The programmer who uses this toolkit is
- constantly encouraged to make a nice looking screen.
- Definitely "home-brewed", these units bear the stamp of
- experience: one programmer knowing what another programmer is
- likely to need. This shows itself in the intuitive names given
- to procedures and functions. A procedure named "TempMessageBox"
- is fairly self-explanatory as to what it is likely to do.
- The Toolkit sells for $49.95 and includes full source code
- to all the units, a printed manual and a diskette full of short
- demo programs showing how to use each of the units.
- I have, on several occasions, written to Bob Ainsbury, the
- so-called "janitor" of TechnoJock Software, Inc., with questions
- or problems about the units. In EVERY CASE I have received
- either a personal letter explaining how to modify the source code
- to do what I want, or, a diskette with a fixed bug. This support
- alone is well worth the price of registration. In addition, there
- 28
- are no royalty payments for using his units in compiled programs
- you distribute and he gives his customers price breaks on
- upgrades, etc.
- Are there any minuses? Yes, I've found two things that may
- stand in your way when using this toolkit. One, a minor
- complaint, is that the manual could be cleaned up. There are
- several inconsistent references to procedure calls and places
- where some information is missing. These errors are not serious
- enough to prohibit your effectively using the manual, but they
- may slow you down at times. A second and more serious
- consideration is getting used to how one uses all the functions
- and procedures in the toolkit. Fortunately, the disk comes with
- an ample supply of programs which demo how to use the various
- units. But be prepared to spend some time looking at these
- programs and studying the code in them. Doing so at the
- beginning will save frustration later. You probably won't hit
- the ground running with this toolkit.
- Beginner and advanced programmers who are looking for a
- workhorse toolbox that can do a lot and get the job done should
- consider TechnoJock's Turbo Toolkit.
- 29
- Turbo Pascal - The Complete Reference
-
- A Review
- By Pete Davis
- I picked this book as my first to review because I feel that
- this book is invaluable for any Turbo Pascal Programmer. The book
- would be useful for everyone from beginner to the veteran Turbo
- Pascal Programmer. Stephen K. O'Brien, the Author is obviously
- very comfortable with Turbo Pascal and his book is official
- enough to have been published by Borland-Osbourne/McGraw-Hill.
- My copy is actually for Version 4 but it has been re-
- released for Version 5.5 of Turbo Pascal, which for the most part
- is almost identical in content with the addition of coverage of
- some 5.5 features.
- The first seven chapters are devoted mostly to the beginner,
- covering everything from basic data structures to program
- structure to the Turbo Pascal environment. Chapter eight then
- begins on more complex ideas like pointers and dynamic memory.
- The explanations of ideas are very clear and to the point
- and the most useful feature is the volume of examples included in
- the text. Almost every idea covered includes examples which drive
- home the point of every section.
- My personal favorite is chapter eighteen : 'Optimizing Turbo
- Pascal Programs', in which the author provides incredible insight
- into how to make you programs run faster and use less memory.
- This chapter alone nearly pays for the book, especially when you
- are involved in large projects where speed and code size are very
- important.
- Another nice feature is the Procedure and Function reference
- near the end of the book. This and other reference areas in the
- book make the Turbo Pascal Reference Guide, which comes with
- Turbo Pascal, almost worthless. (I shouldn't really say that, as
- the reference guide is quite useful, but many of the more
- important aspects are covered in The Complete Reference).
- I give Stephen K. O'Brien five stars for a fantastic book.
- If you have been using Turbo Pascal for a long time, or you are
- just learning to use it, I suggest that you grab a copy and read
- through it. It is by far the most useful book on Turbo Pascal
- that I have ever seen.
- _Pete Davis
- Editor
- 30
- Conclusion
- Well, I would first like to thank everyone for being so
- patient in waiting for the release of this issue of the Pascal
- NewsLetter. I apologize for the delay, but there were a lot of
- things that held this issue up. Some of them, many of you already
- know about. Between my vacation and some computer problems, there
- was about a two week delay.
- When I was just getting ready to start finishing up the
- issue, I got a the Profiler article and program which I just had
- to include in this issue. I think you'll agree that it was worth
- the wait. Getting the article translated to English was the last
- thing holding this issue up, but it was worth the wait for me.
- I would like to thank everyone who contributed to this
- issue, in particular, I would like to thank Bob Gowans for his
- continued support and work in the For Beginners column. I would
- like to thank Jan-Erik Rosinowski for a fantastic program. His
- contributions are welcome here anytime. I would also like to
- thank Howard Sanner for putting in a lot of time in translating
- the article for me. I couldn't have done it without him.
- I have a few surprises that I hope I can spring in the next
- issue, but I can't be sure of whether or not things will go
- through by then. If not, I still plan on having a good issue out.
- Please send in your contributions. They're what keeps this
- newsletter coming out. Even if you don't write well, send in the
- best you can do, and if you're uncomfortable with it, I'll be
- happy to go through and edit it.
- Also, please keep the comments and suggestions coming.
- They're a great help.
- Until the next issue, happy computing.
- _Pete Davis
-
- 31
- The Pascal NewsLetter is Copyrighted by Pete Davis.
- Articles submitted by others are the property of the authors and
- are used with permission. They may not be treated separately
- from this newsletter without the author's permission and thus
- maintain all distribution rules of the newsletter as a whole. It
- may be freely distributed in un-modified form, but no charge
- whatsoever may be incurred on the recipient. All code is provided
- 'as-is' with no guarantees whatsoever.
- The Pascal NewsLetter can be obtained from the following
- locations:
- GEnie : General Electric Network for Information
- Exchange. It is located in the IBMPC
- filelist.
- Simtel : Internet address: 26.2.0.74 or
- Simtel20.ARPA It is located in the
- <MSDOS.PASCAL> directory.
- Programmer's Forum : This is the home of the PNL.
- Each issue can be found in
- the MAG directory from the main area.
- The number is on the title page.
- If you would like to receive back issues of PNL
- directly from me, send a diskette and $2.00 for shipping.
- Don't forget to include your address.
- Send your order to:
- Peter Davis
- 4851 Brandywine St. NW
- Washington, DC 20016
- If you are a SysOp that will regularly carry PNL and
- would like to have your bulletin board listed as such, here,
- send me a message either by postal mail or at one of the
- electronic addresses given on the title page, with your
- bulletin board's name, phone number, and your name.
- 32
- Distribution List
- The following is the phone numbers to bulletin boards known
- to carry PNL. If you would like your bulletin board's name and
- number added to or deleted from this list, please send me a
- message at one of my many addresses. I can not guarantee whether
- a listed board will have any particular issue, however.
- The Programmer's Forum ................. Phone: (202) 966-3647
- The Programmer's Forum is the home of the PNL.
- The Bored .............................. Phone: (512) 303-0471
- Classic City ........................... Phone: (404) 548-0726
- Theive's World ......................... Phone: (713) 463-8053
- Hippocampus ............................ Phone: (203) 484-4621
- Rogers State College BBS ............... Phone: (918) 341-8982
- The Foxtrot BBS ........................ Phone: (914) 567-1814
- Turbo City BBS ......................... Phone: (209) 599-7435
- Austin IEMUG/MIDI BBS .................. Phone: (512) 528-0626
- Laser Publishers ....................... Phone: (918) 438-2749
- Fargo RBBS-PC .......................... Phone: (701) 293-5973
- Momentary Lapse of Reason .............. Phone: (704) 327-6361
- The Demon's Den ........................ Phone: (508) 433-2702
- The Cannibal Cafe ...................... Phone: (508) 840-6589
- IBM Tech FIDO .......................... Phone: (508) 433-6491
- The User Friendly BBS .................. Phone: (704) 323-8223
- The Disseminator BBS (Australia)........ Phone: 61-7-368-1239
- Beyound Frontiers BBS (Denmark)......... Phone: (+45)8694-1609
- Collision Theory ....................... Phone: (703) 503-9441
- Ed-Net 9600 ............................ Phone: (604) 732-8877
-