Back in my VAX days (VMS-4.0 to VMS-6.2) doing any kind of I/O was very expensive so it was always better to concatenate data
before doing any serial I/O (like BASIC's PRINT statement). We proved this using system accounting to measure run-time stats. (not
the best development tool but better than nothing)
When we moved from VAX to Alpha in 1999-2001 we only used OpenVMS-7.x and noticed everything was less costly (I/Os, spawns,
queuing, etc.) but accounting tests proved it was still better to concatenate string data before doing an I/O in BASIC. (caveat:
this was never true in C/C++)
My recent tests with HP-BASIC-1.7 on OpenVMS-8.4 indicate that something has changed (probably for the better) over the past ten-years which now make pre-i/o concatenations unnecessary. This is also the first time I've seen the smallest binary also consume the least amount of system resources on this RISC system.
I do not have an explanation for this (because HP's solution is hidden behind BASIC RTL routines) but can imagine:
| Program | DBASIC$ calls | STR$CONCAT calls | Total Calls | Size of $CODE$ section |
|---|---|---|---|---|
| Neil1.bas | 33 | 0 | 33 | 1004 |
| Neil2.bas | 23 | 10 | 33 | 1084 |
| Neil3.bas | 5 | 15 | 20 | 844 |
| Neil4.bas | 21 | 0 | 21 | 732 |
| Neil5.bas | 15 | 0 | 15 | 552 |
1000 ! neil1.bas (individual PRINT statements) ! Compiled Routine Size: 1156 (optim=level=0) ! Compiled Routine Size: 1004 (optim=level=4) option type=explicit declare string abc$ abc$ = "abc" print '<tr>'; print '<td>'; abc$ ;'</td>'; print '<td>'; abc$ ;'</td>'; print '<td>'; abc$ ;'</td>'; print '<td>'; abc$ ;'</td>'; print '<td>'; abc$ ;'</td>'; print '</tr>' 1040 end
1000 ! neil2.bas (individual PRINT statements; some plus signs) ! Compiled Routine Size: 1236 (optim=level=0) ! Compiled Routine Size: 1084 (optim=level=4) option type=explicit declare string abc$ abc$ = "abc" print '<tr>'; print '<td>'+ abc$ +'</td>'; print '<td>'+ abc$ +'</td>'; print '<td>'+ abc$ +'</td>'; print '<td>'+ abc$ +'</td>'; print '<td>'+ abc$ +'</td>'; print '</tr>' 1040 end
1000 ! neil3.bas (one PRINT, all plus signs) ! Compiled Routine Size: 948 (optim=level=0) ! Compiled Routine Size: 844 (optim=level=4) option type=explicit declare string abc$ abc$ = "abc" print '<tr>'+ & '<td>'+ abc$ +'</td>'+ & '<td>'+ abc$ +'</td>'+ & '<td>'+ abc$ +'</td>'+ & '<td>'+ abc$ +'</td>'+ & '<td>'+ abc$ +'</td>'+ & '</tr>' 1040 end
1000 ! neil4.bas (one PRINT, all semicolons) ! Compiled Routine Size: 868 (optim=level=0) ! Compiled Routine Size: 732 (optim=level=4) option type=explicit declare string abc$ abc$ = "abc" print '<tr>'; & '<td>'; abc$ ;'</td>'; & '<td>'; abc$ ;'</td>'; & '<td>'; abc$ ;'</td>'; & '<td>'; abc$ ;'</td>'; & '<td>'; abc$ ;'</td>'; & '</tr>' 1040 end
1000 ! neil5.bas (one PRINT; mixture of semicolons and plus signs) ! Compiled Routine Size: 580 (optim=level=0) ! Compiled Routine Size: 552 (optim=level=4) option type=explicit declare string abc$ abc$ = "abc" print '<tr>'+ & '<td>'; abc$ ;'</td>'+ & '<td>'; abc$ ;'</td>'+ & '<td>'; abc$ ;'</td>'+ & '<td>'; abc$ ;'</td>'+ & '<td>'; abc$ ;'</td>'+ & '</tr>' 1040 end
NEIL5$MAIN Source Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 1
27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
1 1000 ! neil5.bas (one PRINT; mixture of semicolons and plus signs)
2 ! Compiled Routine Size: 580 (optim=level=0)
3 ! Compiled Routine Size: 552 (optim=level=4)
4 option type=explicit
5 declare string abc$
6 abc$ = "abc"
7 print '<tr>'+ &
8 '<td>'; abc$ ;'</td>'+ &
9 '<td>'; abc$ ;'</td>'+ &
10 '<td>'; abc$ ;'</td>'+ &
11 '<td>'; abc$ ;'</td>'+ &
12 '<td>'; abc$ ;'</td>'+ &
13 '</tr>'
14 1040 end
NEIL5$MAIN Source Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 2
Allocation Map 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
Allocation information for main program NEIL5$MAIN Offset based on (FP)
Name Offset Size Type
ABC$ -8 8 Dynamic string
PROGRAM SECTIONS
Name Bytes Attributes
0 $READ_ONLY$ 132 PIC CON REL LCL SHR NOEXE RD NOWRT OCTA
1 $CODE$ 552 PIC CON REL LCL SHR EXE NORD NOWRT OCTA
2 $LINK$ 216 NOPIC CON REL LCL NOSHR NOEXE RD NOWRT OCTA
3 $LITERAL$ PIC CON REL LCL SHR NOEXE RD NOWRT OCTA
4 $ARRAY 0 NOPIC CON REL LCL NOSHR NOEXE RD WRT OCTA
5 $DESC 0 NOPIC CON REL LCL NOSHR NOEXE RD WRT OCTA
NEIL5$MAIN Source Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 3
Qualifier Summary 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
BASIC/REAL_SIZE=DOUBLE/INTEGER_SIZE=LONG/OPTIM=LEVEL=4/LIST/MACHINE NEIL5.BAS
DEFAULT DATA TYPE INFORMATION: LISTING FILE INFORMATION INCLUDES:
Data type : EXPLICIT List
Real size : DOUBLE NO Cross reference
Integer size : LONG CDD Definitions
Decimal size : (15,2) Environment
Scale factor : 0 NO Override of %NOLIST
NO Round decimal numbers Machine code
Map
COMPILATION QUALIFIERS IN EFFECT: INCLUDE files
Object file
NO Separate_compilation FLAGGERS:
NO Line NO Declining features
Variant : 0
Warnings DEBUG INFORMATION:
Informationals Traceback records
NO Alignment warnings NO Debug symbol records
NO Diagnostics
NO Audit OPTIMIZE SETTINGS:
NO Analysis data Level : 4
NO Placeholders Tune : GENERIC
NO Comments Architecture : GENERIC
Old Version : NO CDD Arrays Overflow check integers
NO Dependency data Overflow check decimal numbers
NO TIE Bounds checking
NO Synchronous exceptions
NEIL5$MAIN Machine Code Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 4
NEIL5$MAIN 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
.PSECT $CODE$, OCTA, PIC, CON, REL, LCL, SHR,-
EXE, NORD, NOWRT
0000 NEIL5$MAIN::
23DEFF00 0000 LDA SP, -256(SP)
A63B0050 0004 LDQ R17, 80(R27)
47E05419 0008 MOV 2, R25
B75E00E0 000C STQ R26, 224(SP)
B77E0000 0010 STQ R27, (SP)
A75BFFD0 0014 LDQ R26, -48(R27)
B7FE0008 0018 STQ R31, 8(SP)
B45E00E8 001C STQ R2, 232(SP)
B47E00F0 0020 STQ R3, 240(SP)
B7BE00F8 0024 STQ FP, 248(SP)
63FF0000 0028 TRAPB
47FE041D 002C MOV SP, FP
23DEFFF0 0030 LDA SP, -16(SP)
47FB0402 0034 MOV R27, R2
221D0008 0038 LDA R16, 8(FP)
A762FFD8 003C LDQ R27, -40(R2)
6B5A4000 0040 JSR R26, DBASIC$INIT ; R26, R26
A7420040 0044 LDQ R26, 64(R2) ; 000006
261F010E 0048 LDAH R16, 270(R31)
404B1000 004C ADDL R2, 88, R0
223D00A8 0050 LDA R17, 168(FP)
B01D00AC 0054 STL R0, 172(FP)
47E05419 0058 MOV 2, R25
22100003 005C LDA R16, 3(R16)
B21D00A8 0060 STL R16, 168(FP)
221DFFF8 0064 LDA R16, ABC$ ; R16, -8(FP)
A7620048 0068 LDQ R27, 72(R2)
2FFE0000 006C UNOP
6B5A4000 0070 JSR R26, STR$COPY_DX ; R26, R26
A742FFE0 0074 LDQ R26, -32(R2) ; 000007
47FF0411 0078 CLR R17
221D0008 007C LDA R16, 8(FP)
47E05419 0080 MOV 2, R25
A762FFE8 0084 LDQ R27, -24(R2)
6B5A4000 0088 JSR R26, DBASIC$PRINT ; R26, R26
A7420030 008C LDQ R26, 48(R2) ; 000008
261F010E 0090 LDAH R16, 270(R31)
404E1000 0094 ADDL R2, 112, R0
47E03419 0098 MOV 1, R25
22100008 009C LDA R16, 8(R16)
B01D00B4 00A0 STL R0, 180(FP)
B21D00B0 00A4 STL R16, 176(FP)
221D00B0 00A8 LDA R16, 176(FP)
A7620038 00AC LDQ R27, 56(R2)
6B5A4000 00B0 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 00B4 LDQ R26, 48(R2)
47E03419 00B8 MOV 1, R25
221DFFF8 00BC LDA R16, ABC$ ; R16, -8(FP)
A7620038 00C0 LDQ R27, 56(R2)
6B5A4000 00C4 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 00C8 LDQ R26, 48(R2) ; 000009
247F010E 00CC LDAH R3, 270(R31)
40421120 00D0 SUBL R2, 16, R0
221D00B8 00D4 LDA R16, 184(FP)
NEIL5$MAIN Machine Code Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 5
NEIL5$MAIN 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
B01D00BC 00D8 STL R0, 188(FP)
20630009 00DC LDA R3, 9(R3)
47E03419 00E0 MOV 1, R25
B07D00B8 00E4 STL R3, 184(FP)
A7620038 00E8 LDQ R27, 56(R2)
2FFE0000 00EC UNOP
6B5A4000 00F0 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 00F4 LDQ R26, 48(R2)
47E03419 00F8 MOV 1, R25
221DFFF8 00FC LDA R16, ABC$ ; R16, -8(FP)
A7620038 0100 LDQ R27, 56(R2)
6B5A4000 0104 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 0108 LDQ R26, 48(R2) ; 000010
40421120 010C SUBL R2, 16, R0
47E03419 0110 MOV 1, R25
221D00C0 0114 LDA R16, 192(FP)
B01D00C4 0118 STL R0, 196(FP)
B07D00C0 011C STL R3, 192(FP)
A7620038 0120 LDQ R27, 56(R2)
6B5A4000 0124 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 0128 LDQ R26, 48(R2)
221DFFF8 012C LDA R16, ABC$ ; R16, -8(FP)
47E03419 0130 MOV 1, R25
A7620038 0134 LDQ R27, 56(R2)
6B5A4000 0138 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 013C LDQ R26, 48(R2) ; 000011
40421120 0140 SUBL R2, 16, R0
47E03419 0144 MOV 1, R25
221D00C8 0148 LDA R16, 200(FP)
B01D00CC 014C STL R0, 204(FP)
B07D00C8 0150 STL R3, 200(FP)
A7620038 0154 LDQ R27, 56(R2)
6B5A4000 0158 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 015C LDQ R26, 48(R2)
47E03419 0160 MOV 1, R25
A7620038 0164 LDQ R27, 56(R2)
221DFFF8 0168 LDA R16, ABC$ ; R16, -8(FP)
2FFE0000 016C UNOP
6B5A4000 0170 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 0174 LDQ R26, 48(R2) ; 000012
40421120 0178 SUBL R2, 16, R0
221D00D0 017C LDA R16, 208(FP)
47E03419 0180 MOV 1, R25
B01D00D4 0184 STL R0, 212(FP)
B07D00D0 0188 STL R3, 208(FP)
A7620038 018C LDQ R27, 56(R2)
6B5A4000 0190 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A7420030 0194 LDQ R26, 48(R2)
47E03419 0198 MOV 1, R25
221DFFF8 019C LDA R16, ABC$ ; R16, -8(FP)
A7620038 01A0 LDQ R27, 56(R2)
6B5A4000 01A4 JSR R26, DBASIC$OUT_T_DX_S ; R26, R26
A742FFC0 01A8 LDQ R26, -64(R2) ; 000013
243F010E 01AC LDAH R1, 270(R31)
404A1123 01B0 SUBL R2, 80, R3
221D00D8 01B4 LDA R16, 216(FP)
B07D00DC 01B8 STL R3, 220(FP)
NEIL5$MAIN Machine Code Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 6
NEIL5$MAIN 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
2021000A 01BC LDA R1, 10(R1)
47E03419 01C0 MOV 1, R25
B03D00D8 01C4 STL R1, 216(FP)
A762FFC8 01C8 LDQ R27, -56(R2)
2FFE0000 01CC UNOP
6B5A4000 01D0 JSR R26, DBASIC$OUT_T_DX_B ; R26, R26
A7420060 01D4 LDQ R26, 96(R2)
47E03419 01D8 MOV 1, R25
221D0008 01DC LDA R16, 8(FP)
A7620068 01E0 LDQ R27, 104(R2)
6B5A4000 01E4 JSR R26, DBASIC$IO_END ; R26, R26
01E8 L$2: ; 000014
A742FFA0 01E8 LDQ R26, -96(R2)
221D0008 01EC LDA R16, 8(FP)
63FF0000 01F0 TRAPB
47E03419 01F4 MOV 1, R25
A762FFA8 01F8 LDQ R27, -88(R2)
2FFE0000 01FC UNOP
6B5A4000 0200 JSR R26, DBASIC$END ; R26, R26
63FF0000 0204 TRAPB ; 000001
47FD041E 0208 MOV FP, SP
A75D00E0 020C LDQ R26, 224(FP)
A45D00E8 0210 LDQ R2, 232(FP)
47E03400 0214 MOV 1, R0 ; 000014
A47D00F0 0218 LDQ R3, 240(FP) ; 000001
A7BD00F8 021C LDQ FP, 248(FP)
23DE0100 0220 LDA SP, 256(SP)
6BFA8001 0224 RET R26
Routine Size: 552 bytes, Routine Base: $CODE$ + 0000
.PSECT $LINK$, OCTA, NOPIC, CON, REL, LCL,-
NOSHR, NOEXE, RD, NOWRT
0000 .LINKAGE DBASIC$END
64742F3C 0010 .ASCII \</td></tr>\
742F3C3E 0014
3E72 0018
0020 .LINKAGE DBASIC$OUT_T_DX_B
0030 .LINKAGE DBASIC$INIT
0040 .LINKAGE DBASIC$PRINT
64742F3C 0050 .ASCII \</td><td>\
64743C3E 0054
3E 0058
0060 ; Stack-Frame invocation descriptor
Entry point: NEIL5$MAIN
Entry Length: 48
Static Handler: DBASIC$HANDLER
Registers used: R0-R3, R16-R17, R25-R26, R28-FP
Registers saved: R2-R3, FP
Fixed Stack Size: 256
00000000 ; Handler data for DBASIC$HANDLER
00000000
00000000
NEIL5$MAIN Machine Code Listing 27-OCT-2013 10:12:01 Alpha BASIC V1.7-001 Page 7
NEIL5$MAIN 27-OCT-2013 09:37:13 CSMIS$USER3:[ADMCSM.NEIL]NEIL5.BAS;2
00000000
0090 .LINKAGE DBASIC$OUT_T_DX_S
00A0 .LINKAGE STR$COPY_DX
00000000 00B0 .ADDRESS $READ_ONLY$
636261 00B8 .ASCII \abc\
00C0 .LINKAGE DBASIC$IO_END
3E72743C 00D0 .ASCII \<tr><td>\
3E64743C 00D4
.PSECT $READ_ONLY$, OCTA, PIC, CON, REL, LCL,-
SHR, NOEXE, RD, NOWRT
$$1:
00000008 0000 .LONG X^8 , - ; .LONG 8
00000001 0004 .LONG X^1 , - ; .LONG 1
00000000 0008 .LONG X^0 , - ; .LONG 0
00000000 000C .LONG X^0 , - ; .LONG 0
000000B8 0010 .LONG X^B8 , - ; .LONG 184
00000000 0014 .LONG X^0 , - ; .LONG 0
0000007C 0018 .LONG X^7C , - ; .LONG 124
00000084 001C .LONG X^84 , - ; .LONG 132
00000084 0020 .LONG X^84 , - ; .LONG 132
00000084 0024 .LONG X^84 , - ; .LONG 132
00000000 0028 .LONG X^0 , - ; .LONG 0
00000000 002C .LONG X^0 , - ; .LONG 0
00000084 0030 .LONG X^84 , - ; .LONG 132
00000000 0034 .LONG X^0 , - ; .LONG 0
00000000 0038 .LONG X^0 , - ; .LONG 0
00000000 003C .LONG X^0 , - ; .LONG 0
00000000 0040 .LONG X^0 , - ; .LONG 0
FFFFFFF8 0044 .LONG X^FFFFFFF8 , - ; .LONG -8
00000000 0048 .LONG X^0 , - ; .LONG 0
FFFFFFF0 004C .LONG X^FFFFFFF0 , - ; .LONG -16
00000001 0050 .LONG X^1 , - ; .LONG 1
00000000 0054 .LONG X^0 , - ; .LONG 0
00000000 0058 .LONG X^0 , - ; .LONG 0
00000000 005C .LONG X^0 , - ; .LONG 0
00000000 0060 .LONG X^0 , - ; .LONG 0
00004080 0064 .LONG X^4080 , - ; .LONG 16512
00000000 0068 .LONG X^0 , - ; .LONG 0
00000000 006C .LONG X^0 , - ; .LONG 0
00000000 0070 .LONG X^0 , - ; .LONG 0
00000000 0074 .LONG X^0 , - ; .LONG 0
00000000 0078 .LONG X^0 ; .LONG 0
$$2:
05 007C .SIGNED_BYTE X^5 ; .SIGNED_BYTE 5
4C49454E 007D .ASCII \NEIL5\
35 0081
Note: The resulting executable can be run directly by Apache. Just drop it in [.scripts] or [.cgi-bin]
1000 ! Neil Rieck
declare string constant k_program = "neil5_www.bas"
declare string abc$ ,&
long i%
abc$ = "abc"
margin #0, 1999888777 !
print 'status: 200' ! http status code
print 'content-type: text/html' !
print ! end of http block
print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"'
print ' "http://www.w3.org/TR/html4/strict.dtd">'
print '<html>'
print '<head><title>'+ k_program +'</title></head>'
print '<meta content="text/html; charset=windows-1252" http-equiv="Content-Type">'
print '<body>'
print '<p>'+ k_program +'</p>'
print '<table>'
for i% = 1 to 2000
print '<tr>' + &
'<td>'; abc$ ;'</td>'+ &
'<td>'; abc$ ;'</td>'+ &
'<td>'; abc$ ;'</td>'+ &
'<td>'; abc$ ;'</td>'+ &
'<td>'; abc$ ;'</td>'+ &
'</tr>'
next i%
print '</table>'
print '</body>'
print '</html>'
end
Back to Home