When you are trying to divide some data into a series of 4k blocks, the
last block is usually short.
I was hoping to trick substr() into returning this short block by
setting the pad character to null (''):
Length = length(data)
Offset = 1
Do while O <= Length
Block = substr(data,offset,4096,'')
Say 'Block length:' length(block)
End
� but substr insists that the pad character be a single character (if it
is specified).
Without this ability I have to use a different substr call for the last
block, and that has always seemed a little messy to me.
Is there an easy way around this? My usual approach is to code my own
function, such as xsubstr() which has the extra facility that I'm
looking for.
I don't want to change the value of data inside the loop above, as that
performs poorly when the data is very long (e.g. 600Mb from an ISO image)
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
9/30/2009 11:11:26 AM |
|
On 30 Sep, 12:11, Swifty <steve.j.sw...@gmail.com> wrote:
> When you are trying to divide some data into a series of 4k blocks, the
> last block is usually short.
>
> I was hoping to trick substr() into returning this short block by
> setting the pad character to null (''):
>
> Length =3D length(data)
> Offset =3D 1
> Do while O <=3D Length
> =A0 =A0Block =3D substr(data,offset,4096,'')
> =A0 =A0Say 'Block length:' length(block)
> =A0 =A0End
>
> =85 but substr insists that the pad character be a single character (if i=
t
> is specified).
>
I was about to offer some suggestions, but then I realised that I
couldn't figure out what was happening here.
Where does O get a value?
How does offset ever become anything other than 1?
Assuming that O does get a value, how does it ever then become <=3D 0?
|
|
0
|
|
|
|
Reply
|
Captain
|
9/30/2009 12:49:57 PM
|
|
Swifty wrote:
> When you are trying to divide some data into a series of 4k blocks, the
> last block is usually short.
>
> I was hoping to trick substr() into returning this short block by
> setting the pad character to null (''):
>
> Length = length(data)
> Offset = 1
> Do while O <= Length
> Block = substr(data,offset,4096,'')
> Say 'Block length:' length(block)
> End
>
> � but substr insists that the pad character be a single character (if it
> is specified).
>
> Without this ability I have to use a different substr call for the last
> block, and that has always seemed a little messy to me.
>
> Is there an easy way around this? My usual approach is to code my own
> function, such as xsubstr() which has the extra facility that I'm
> looking for.
>
> I don't want to change the value of data inside the loop above, as that
> performs poorly when the data is very long (e.g. 600Mb from an ISO image)
>
data=Copies(0, 34567)
Do offset=1 To Length(data) By 4096
Parse Var data =(offset) block =(offset+4096)
Say 'Block length:' Length(block)
End
Jon Hosking
|
|
0
|
|
|
|
Reply
|
Jonathan
|
9/30/2009 3:07:26 PM
|
|
How about using D2C(0) rather than the empty string?
|
|
0
|
|
|
|
Reply
|
Dark
|
9/30/2009 3:29:48 PM
|
|
Captain Paralytic wrote:
> I was about to offer some suggestions, but then I realised that I
> couldn't figure out what was happening here.
>
> Where does O get a value?
> How does offset ever become anything other than 1?
> Assuming that O does get a value, how does it ever then become <= 0?
My apologies. I coded it using "O" (less typing) but then screwed up the
change to "Offset". So:
Change "O" to "Offset"
Insert: Offset = Offset + 4096
Not one of my better efforts.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
9/30/2009 6:22:32 PM
|
|
Dark Coffee wrote:
> How about using D2C(0) rather than the empty string?
That would pad with null characters. I'm transmitting a tgz file in
4096-byte chunks, and I suspect that the additional trailing nulls would
upset the tgz processing. I had wondered what would happen if I tried that.
The specification of substr() doesn't leave much (if any) room for some
back-door mechanism. It I'd tried to pad with d2c(0) characters, and
they got stripped, I'd be even more upset.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
9/30/2009 6:26:27 PM
|
|
Dark Coffee wrote:
> How about using D2C(0) rather than the empty string?
That would pad with null characters. I'm transmitting a tgz file in
4096-byte chunks, and I suspect that the additional trailing nulls would
upset the tgz processing. I had wondered what would happen if I tried that.
The specification of substr() doesn't leave much (if any) room for some
back-door mechanism. It I'd tried to pad with d2c(0) characters, and
they got stripped, I'd be even more upset.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
9/30/2009 6:26:49 PM
|
|
Jonathan Hosking wrote:
> data=Copies(0, 34567)
> Do offset=1 To Length(data) By 4096
> Parse Var data =(offset) block =(offset+4096)
> Say 'Block length:' Length(block)
> End
I'll do it that way. Thanks.
Incidentally, here is my first attempt at an xsubstr function that does
no padding if the pad character is omitted, or null:
::Routine xsubstr public
Parse arg text,offset,length,pad
If length = '' then return substr(text,offset)
If length(text)>=offset+length-1 then return substr(text,offset,length)
If pad == '' then return substr(text,offset)
Return substr(text,offset,length,pad)
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
9/30/2009 6:30:45 PM
|
|
In Message-ID:<4ac3742f$1@kcnews01>,
Jonathan Hosking <jh910@juno.com> wrote:
>Swifty wrote:
>> When you are trying to divide some data into a series of 4k blocks, the
>> last block is usually short.
>>
<snip>
>> Is there an easy way around this? My usual approach is to code my own
>> function, such as xsubstr() which has the extra facility that I'm
>> looking for.
>>
>> I don't want to change the value of data inside the loop above, as that
>> performs poorly when the data is very long (e.g. 600Mb from an ISO image)
>>
>
>data=Copies(0, 34567)
>Do offset=1 To Length(data) By 4096
> Parse Var data =(offset) block =(offset+4096)
> Say 'Block length:' Length(block)
>End
That example gave me syntax errors under Regina. This works
for me:
data=Copies(0, 34567)
Do offset=1 To Length(data) By 4096
Parse Var data =(offset) block +4096
Say 'Block length:' Length(block)
End
It also works when made a bit more friendly to changing block
sizes:
data=Copies(0, 34567)
blksize = 4096
Do offset=1 To Length(data) By blksize
Parse Var data =(offset) block +(blksize)
Say 'Block length:' Length(block)
End
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
9/30/2009 6:39:31 PM
|
|
I'm curious... what does Regina complain about?
Les (Change Arabic to Roman to email me)
Arthur T. wrote:
> In Message-ID:<4ac3742f$1@kcnews01>,
> Jonathan Hosking <jh910@juno.com> wrote:
>
>> Swifty wrote:
>>> When you are trying to divide some data into a series of 4k blocks, the
>>> last block is usually short.
>>>
> <snip>
>>> Is there an easy way around this? My usual approach is to code my own
>>> function, such as xsubstr() which has the extra facility that I'm
>>> looking for.
>>>
>>> I don't want to change the value of data inside the loop above, as that
>>> performs poorly when the data is very long (e.g. 600Mb from an ISO image)
>>>
>> data=Copies(0, 34567)
>> Do offset=1 To Length(data) By 4096
>> Parse Var data =(offset) block =(offset+4096)
>> Say 'Block length:' Length(block)
>> End
>
> That example gave me syntax errors under Regina. This works
> for me:
>
> data=Copies(0, 34567)
> Do offset=1 To Length(data) By 4096
> Parse Var data =(offset) block +4096
> Say 'Block length:' Length(block)
> End
>
> It also works when made a bit more friendly to changing block
> sizes:
>
> data=Copies(0, 34567)
> blksize = 4096
> Do offset=1 To Length(data) By blksize
> Parse Var data =(offset) block +(blksize)
> Say 'Block length:' Length(block)
> End
>
|
|
0
|
|
|
|
Reply
|
LesK
|
9/30/2009 10:52:09 PM
|
|
In Message-ID:<4ac3e0aa$0$5635$9a6e19ea@unlimited.newshosting.com>,
LesK <5mre20@tampabay.rr.com> wrote:
>I'm curious... what does Regina complain about?
Error 38 running "F:\A.REX", line 3: Invalid template or pattern
Error 38.1: Invalid parsing template detected at "+"
Apparently it doesn't like the plus sign inside the parens.
Line 3, of course, is:
Parse Var data =(offset) block =(offset+4096)
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/1/2009 12:29:15 AM
|
|
On Oct 1, 10:29=A0am, Arthur T. <art...@munged.invalid> wrote:
> In Message-ID:<4ac3e0aa$0$5635$9a6e1...@unlimited.newshosting.com>,
>
> LesK <5mr...@tampabay.rr.com> wrote:
> >I'm curious... what does Regina complain about?
>
> =A0Error 38 running "F:\A.REX", line 3: Invalid template or pattern
> =A0Error 38.1: Invalid parsing template detected at "+"
>
> =A0 =A0 =A0Apparently it doesn't like the plus sign inside the parens.
> Line 3, of course, is:
> =A0 =A0Parse Var data =3D(offset) block =3D(offset+4096)
>
> --
> Arthur T. - ar23hur "at" intergate "dot" com
> Looking for a z/OS (IBM mainframe) systems programmer position
The use of an expression inside parentheses in a PARSE template is an
ooRexx extension to the ANSI specification. ANSI states that what can
be inside parentheses is a variable; not an expression.
|
|
0
|
|
|
|
Reply
|
markh
|
10/1/2009 7:06:49 AM
|
|
Arthur T. wrote:
> It also works when made a bit more friendly to changing block sizes:
>
> data=Copies(0, 34567)
> blksize = 4096
> Do offset=1 To Length(data) By blksize
> Parse Var data =(offset) block +(blksize)
> Say 'Block length:' Length(block)
> End
Well, I'm actually using a blocksize of 16384 but it was hard to avoid
line splitting, so I shrank my blocksize for the example. I'm also using
the blocksize specified in a variable.
So, you have basically written my whole routine for me. Do you take
commissions? :-)
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/1/2009 8:22:39 AM
|
|
In Message-ID:<JZidnfjN5I5E-1nXnZ2dnUVZ8jVi4p2d@brightview.com>,
Swifty <steve.j.swift@gmail.com> wrote:
>Arthur T. wrote:
>> It also works when made a bit more friendly to changing block sizes:
>>
>> data=Copies(0, 34567)
>> blksize = 4096
>> Do offset=1 To Length(data) By blksize
>> Parse Var data =(offset) block +(blksize)
>> Say 'Block length:' Length(block)
>> End
>
>Well, I'm actually using a blocksize of 16384 but it was hard to avoid
>line splitting, so I shrank my blocksize for the example. I'm also using
>the blocksize specified in a variable.
>
>So, you have basically written my whole routine for me.
In this case, Jonathan Hosking did most of the work.
>Do you take
>>commissions? :-)
I'm out of a job, so I'll take almost anything. But the price
for a routine this small wouldn't be worth the postage.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/1/2009 1:34:10 PM
|
|
In Message-ID:<JZidnfjN5I5E-1nXnZ2dnUVZ8jVi4p2d@brightview.com>,
Swifty <steve.j.swift@gmail.com> wrote:
>Arthur T. wrote:
>> It also works when made a bit more friendly to changing block sizes:
>>
>> data=Copies(0, 34567)
>> blksize = 4096
>> Do offset=1 To Length(data) By blksize
>> Parse Var data =(offset) block +(blksize)
>> Say 'Block length:' Length(block)
>> End
>
>Well, I'm actually using a blocksize of 16384 but it was hard to avoid
>line splitting, so I shrank my blocksize for the example. I'm also using
>the blocksize specified in a variable.
>
>So, you have basically written my whole routine for me. Do you take
>commissions? :-)
Of course, if you want *real* speed, try something like this
Q&D program:
<code>
file = "inputfile" /* large enough to populate DATA */
tmpfile = "x:\testfile" /* temp file */
totsize = 0
lenfile = chars(file)
t0 = time('r')
data = charin(file,,lenfile)
/* DATA is now poplulated */
t1 = time('r')
x = charout(tmpfile,data)
t2 = time('r')
signal on NOTREADY
blksize = 40960 * 4 /* a reasonable size for my DATA */
Do forever
left = chars(tmpfile)
select
when left = 0 then signal NOTREADY
when left < blksize then blksize = left
otherwise nop
end /* select */
block = charin(tmpfile,,blksize)
Say 'Block length:' Length(block)
totsize = totsize + blksize
End
NOTREADY:
t3 = time('r')
say lenfile totsize
say t1 t2 t3
exit 0
</code>
Just make sure your tempfile is deleted between runs.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/1/2009 11:12:17 PM
|
|
In Message-ID:<f8dac5lv36705c1ooneku2sed00ob46c0g@4ax.com>,
Arthur T. <arthur@munged.invalid> wrote:
> Of course, if you want *real* speed, try something like this
>Q&D program:
Slightly improved example showing that the write/read-back
method is about 70 times the speed of the PARSE technique (on my
machine). Here's the output when I ran it:
1.344000 2.078000 1.687000 119.313000 70.7249555
And here is "it":
tmpfile = "x:\testfile"
totsize = 0
t0 = time('r')
lenfile = 64*1024*1024
data = copies(' ',lenfile)
t1 = time('r')
x = charout(tmpfile,data,1)
t2 = time('r')
signal on NOTREADY
blksize = 40960 * 4
Do forever
left = chars(tmpfile)
select
when left = 0 then leave
when left < blksize then blksize = left
otherwise nop
end /* select */
block = charin(tmpfile,,blksize)
Say 'Block length:' Length(block)
totsize = totsize + blksize
End
NOTREADY:
t3 = time('r')
say lenfile totsize
blksize = 40960 * 4
totsize = 0
Do offset=1 To Length(data) By blksize
Parse Var data =(offset) block +(blksize)
Say 'Block length:' Length(block)
totsize = totsize + length(block)
End
t4 = time('r')
say lenfile totsize
say t1 t2 t3 t4 t4/t3
exit 0
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/2/2009 5:03:42 AM
|
|
Parse isn't optimized for the pc like it is for the mainframe.
Les (Change Arabic to Roman to email me)
Arthur T. wrote:
> In Message-ID:<f8dac5lv36705c1ooneku2sed00ob46c0g@4ax.com>,
> Arthur T. <arthur@munged.invalid> wrote:
>
>> Of course, if you want *real* speed, try something like this
>> Q&D program:
>
> Slightly improved example showing that the write/read-back
> method is about 70 times the speed of the PARSE technique (on my
> machine). Here's the output when I ran it:
>
> 1.344000 2.078000 1.687000 119.313000 70.7249555
>
> And here is "it":
>
> tmpfile = "x:\testfile"
> totsize = 0
>
> t0 = time('r')
> lenfile = 64*1024*1024
> data = copies(' ',lenfile)
> t1 = time('r')
>
> x = charout(tmpfile,data,1)
>
> t2 = time('r')
>
> signal on NOTREADY
> blksize = 40960 * 4
> Do forever
> left = chars(tmpfile)
> select
> when left = 0 then leave
> when left < blksize then blksize = left
> otherwise nop
> end /* select */
> block = charin(tmpfile,,blksize)
> Say 'Block length:' Length(block)
> totsize = totsize + blksize
> End
>
> NOTREADY:
> t3 = time('r')
>
> say lenfile totsize
>
> blksize = 40960 * 4
> totsize = 0
> Do offset=1 To Length(data) By blksize
> Parse Var data =(offset) block +(blksize)
> Say 'Block length:' Length(block)
> totsize = totsize + length(block)
> End
>
> t4 = time('r')
> say lenfile totsize
> say t1 t2 t3 t4 t4/t3
>
> exit 0
>
>
>
>
|
|
0
|
|
|
|
Reply
|
LesK
|
10/2/2009 6:37:27 AM
|
|
LesK wrote:
> Parse isn't optimized for the pc like it is for the mainframe.
I did a simple benchmark (the code is at the bottom). Here are the results:
System Parse Substr
Home PC (4 year old) 1.608 1.969
Office server (7 years) 3.535 3.882
Swiftys.org.uk 0.774 0.879
The office server is showing its age. It was stupendously quick when it
was purchased about 7 years ago. My "swiftys" website is on a new Dell
server (not actually in production yet). My home PC is showing its age,
but then I'm showing my age more, so I don't mind. All of the systems
are "PC" architecture. Home/Office both run IBM Object REXX. "Swiftys"
is ooRexx 4.0
Code:
/* Benchmark SUBSTR vs. Parse */
Buffer= copies('F0'x,2**21+1234)
Blocksize = 2**14
Loops = 1000
Say 'Buffer length:' length(buffer) 'Blocksize;' blocksize
Say
Time. = 0
Do loops
Call Parse_It
Call Substr_it
End
Say 'Parse: ' time.parse
Say 'Substr:' time.substr
Call charout,'0A'x || 'Press any key to exit: '
Call sysgetkey 'NOECHO'
Exit
Parse_it: Procedure expose Buffer blocksize time.
Call time 'R'
Do offset=1 To Length(buffer) By blocksize
Parse Var buffer =(offset) block +(blocksize)
End
Time.parse = time.parse + time('E')
Return
Substr_It: Procedure expose Buffer blocksize time. blocks
Call time 'R'
L = Length(buffer)
Do offset = 1 to L by blocksize
If Offset+blocksize < L then block = substr(buffer,offset,blocksize)
Else block = substr(buffer,offset)
End
Time.substr = time.substr + time('E')
Return
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/2/2009 9:37:28 AM
|
|
In Message-ID:<MIydnXeqxZF7VFjXnZ2dnUVZ8mmdnZ2d@brightview.com>,
Swifty <steve.j.swift@gmail.com> wrote:
>I did a simple benchmark (the code is at the bottom). Here are the results:
>
>System Parse Substr
>Home PC (4 year old) 1.608 1.969
>Office server (7 years) 3.535 3.882
>Swiftys.org.uk 0.774 0.879
My machine is about 7 years old, too, but I had to cut the
number of loops down to just 10 to get these numbers:
Parse: 11.718000
Substr: 11.673000
Then I added the write/read method and got:
Parse: 11.344000
Substr: 11.688000
Read: 0.906000
I'd be interested to see the numbers from your machines (with a
suitable LOOPS value). If you run it, remember to code a reasonable
name for TMPFILE.
Here's my code:
/* Benchmark SUBSTR vs. Parse */
Buffer= copies('F0'x,2**21+1234)
Blocksize = 2**14
Loops = 10
Say 'Buffer length:' length(buffer) 'Blocksize;' blocksize
Say
Time. = 0
Do loops
Call Parse_It
Call Substr_it
Call Read_it
End
Say 'Parse: ' time.parse
Say 'Substr:' time.substr
Say 'Read: ' time.read
Call charout,'0A'x || 'Press any key to exit: '
Call sysgetkey 'NOECHO'
Exit
Parse_it: Procedure expose Buffer blocksize time.
Call time 'R'
Do offset=1 To Length(buffer) By blocksize
Parse Var buffer =(offset) block +(blocksize)
End
Time.parse = time.parse + time('E')
Return
Substr_It: Procedure expose Buffer blocksize time. blocks
Call time 'R'
L = Length(buffer)
Do offset = 1 to L by blocksize
If Offset+blocksize < L then block =
substr(buffer,offset,blocksize)
Else block = substr(buffer,offset)
End
Time.substr = time.substr + time('E')
Return
Read_it: Procedure expose Buffer blocksize time.
Call time 'R'
signal on NOVALUE
tmpfile = 'x:\testfile'
x = charout(tmpfile,Buffer,1)
blksize = blocksize
Do forever
left = chars(tmpfile)
select
when left = 0 then leave
when left < blksize then blksize = left
otherwise nop
end /* select */
block = charin(tmpfile,,blksize)
End
NOVALUE:
Time.read = time.read + time('E')
Return
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/2/2009 5:05:33 PM
|
|
"Arthur T." wrote:
> when left < blksize then blksize = left
Is this necessary? Doesn't charin() return "up to length" characters,
up to the end of the input stream? I'd think this should suffice:
Do while chars(tmpfile) > 0
block = charin(tmpfile,,blksize)
...
End
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
10/2/2009 5:23:18 PM
|
|
I wrote:
> up to the end of the input stream? I'd think this should suffice:
> Do while chars(tmpfile) > 0
--not to mention that it would also work on platforms where CHARS()
doesn't have access to the actual size of the file, and returns only 0
or 1.
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
10/2/2009 5:32:58 PM
|
|
These numbers looked a bit suspect to me, so I tried running this
myself. I got similar results, which puzzled me, but I tracked it down
to the name of the temporary file "x:\testfile". I don't have an X
drive on my system, so the loop was terminating on the first pass. When
I changed this to c:, I got the following results:
Parse: 0.016000
Substr: 0.016000
Read: 03590000
The parse and read results are right up at the limits of the PC time of
day clock.
Rick
Arthur T. wrote:
> In Message-ID:<MIydnXeqxZF7VFjXnZ2dnUVZ8mmdnZ2d@brightview.com>,
> Swifty <steve.j.swift@gmail.com> wrote:
>
>> I did a simple benchmark (the code is at the bottom). Here are the results:
>>
>> System Parse Substr
>> Home PC (4 year old) 1.608 1.969
>> Office server (7 years) 3.535 3.882
>> Swiftys.org.uk 0.774 0.879
>
> My machine is about 7 years old, too, but I had to cut the
> number of loops down to just 10 to get these numbers:
>
> Parse: 11.718000
> Substr: 11.673000
>
> Then I added the write/read method and got:
>
> Parse: 11.344000
> Substr: 11.688000
> Read: 0.906000
>
> I'd be interested to see the numbers from your machines (with a
> suitable LOOPS value). If you run it, remember to code a reasonable
> name for TMPFILE.
>
> Here's my code:
>
> /* Benchmark SUBSTR vs. Parse */
> Buffer= copies('F0'x,2**21+1234)
> Blocksize = 2**14
> Loops = 10
> Say 'Buffer length:' length(buffer) 'Blocksize;' blocksize
> Say
> Time. = 0
> Do loops
> Call Parse_It
> Call Substr_it
> Call Read_it
> End
> Say 'Parse: ' time.parse
> Say 'Substr:' time.substr
> Say 'Read: ' time.read
> Call charout,'0A'x || 'Press any key to exit: '
> Call sysgetkey 'NOECHO'
> Exit
>
> Parse_it: Procedure expose Buffer blocksize time.
> Call time 'R'
> Do offset=1 To Length(buffer) By blocksize
> Parse Var buffer =(offset) block +(blocksize)
> End
> Time.parse = time.parse + time('E')
> Return
>
> Substr_It: Procedure expose Buffer blocksize time. blocks
> Call time 'R'
> L = Length(buffer)
> Do offset = 1 to L by blocksize
> If Offset+blocksize < L then block =
> substr(buffer,offset,blocksize)
> Else block = substr(buffer,offset)
> End
> Time.substr = time.substr + time('E')
> Return
>
> Read_it: Procedure expose Buffer blocksize time.
> Call time 'R'
> signal on NOVALUE
> tmpfile = 'x:\testfile'
> x = charout(tmpfile,Buffer,1)
> blksize = blocksize
> Do forever
> left = chars(tmpfile)
> select
> when left = 0 then leave
> when left < blksize then blksize = left
> otherwise nop
> end /* select */
> block = charin(tmpfile,,blksize)
> End
> NOVALUE:
> Time.read = time.read + time('E')
> Return
>
>
|
|
0
|
|
|
|
Reply
|
Rick
|
10/2/2009 6:18:57 PM
|
|
In Message-ID:<lurxm.19409$Fg7.7247@newsfe03.iad>,
Rick McGuire <object.rexx@gmail.com> wrote:
>These numbers looked a bit suspect to me, so I tried running this
>myself. I got similar results, which puzzled me, but I tracked it down
>to the name of the temporary file "x:\testfile". I don't have an X
>drive on my system, so the loop was terminating on the first pass. When
> I changed this to c:, I got the following results:
>
>Parse: 0.016000
>Substr: 0.016000
>Read: 03590000
>
>The parse and read results are right up at the limits of the PC time of
>day clock.
Those are numbers I'd more expect. In my tests, I even did a
verify that the disk file was there and properly filled. I wonder
what's slowing my machine down so much for the PARSE & SUBSTR
routines. Thanks for running my version.
I just noticed that there's no decimal point in the READ: line.
How long did it actually take?
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/2/2009 7:18:56 PM
|
|
On 1 Oct, 09:06, markh <r...@users.sourceforge.net> wrote:
> On Oct 1, 10:29=A0am, Arthur T. <art...@munged.invalid> wrote:
>
> > In Message-ID:<4ac3e0aa$0$5635$9a6e1...@unlimited.newshosting.com>,
>
> > LesK <5mr...@tampabay.rr.com> wrote:
> > >I'm curious... what does Regina complain about?
>
> > =A0Error 38 running "F:\A.REX", line 3: Invalid template or pattern
> > =A0Error 38.1: Invalid parsing template detected at "+"
>
> > =A0 =A0 =A0Apparently it doesn't like the plus sign inside the parens.
> > Line 3, of course, is:
> > =A0 =A0Parse Var data =3D(offset) block =3D(offset+4096)
>
>
> The use of an expression inside parentheses in a PARSE template is an
> ooRexx extension to the ANSI specification. ANSI states that what can
> be inside parentheses is a variable; not an expression.
not tested (Internet Cafe without rexx) - would this be ANSI:
parse value (offset + 4096) data with b =3D(offset) block =3D(b)
but even easier would be be:
l =3D length(data)
do while l > offset /* or length(data) > offset - something to
optimize */
parse var data block =3D(offset) data
l =3D l - offset /* not so in the length() case */
...
end
block =3D data
....
btw., if blocksize should be like 4096, offset should be 4097
Wolfgang
|
|
0
|
|
|
|
Reply
|
wolfgang
|
10/2/2009 8:06:49 PM
|
|
wolfgang.riedel wrote:
> On 1 Oct, 09:06, markh <r...@users.sourceforge.net> wrote:
> but even easier would be be:
> l = length(data)
> do while l > offset /* or length(data) > offset - something to
> optimize */
> parse var data block =(offset) data
> l = l - offset /* not so in the length() case */
> ...
> end
> block = data
> ...
That is the sort of code that I try to avoid, especially when
length(data) is likely to start at something like 600000000.
I know that the new value of "data" will be stored in the memory used by
the old version (because it is always shorter), so the performance
problem is nowhere near as bad as when you join the block using a
similar technique. But I suspect that setting the variable "data" 146484
times will slow things down.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/3/2009 8:53:21 AM
|
|
Rick McGuire wrote:
> Parse: 0.016000
> Substr: 0.016000
> Read: 03590000
>
> The parse and read results are right up at the limits of the PC time of
> day clock.
If you were using my code unaltered, then your system is nearly 50 times
faster than the fastest system I have access to. Would you mind telling
me what it is, so I can suggest it to my manager when my PC renewal
comes up (some time in 2010).
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/3/2009 9:00:21 AM
|
|
Arthur T. wrote:
> I'd be interested to see the numbers from your machines (with a
> suitable LOOPS value). If you run it, remember to code a reasonable
> name for TMPFILE.
I'd only run that on a system that had a "Disk in Memory" filesystem
(only the Office System).
I presume you're working on the assumption that the write won't get
committed to disk if you don't close the file, but I'm not sure how true
that might be on a 600Mb block of data.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/3/2009 9:03:32 AM
|
|
Arthur T. wrote:
> In Message-ID:<lurxm.19409$Fg7.7247@newsfe03.iad>,
> Rick McGuire <object.rexx@gmail.com> wrote:
>
>> These numbers looked a bit suspect to me, so I tried running this
>> myself. I got similar results, which puzzled me, but I tracked it down
>> to the name of the temporary file "x:\testfile". I don't have an X
>> drive on my system, so the loop was terminating on the first pass. When
>> I changed this to c:, I got the following results:
>>
>> Parse: 0.016000
>> Substr: 0.016000
>> Read: 03590000
>>
>> The parse and read results are right up at the limits of the PC time of
>> day clock.
>
> Those are numbers I'd more expect. In my tests, I even did a
> verify that the disk file was there and properly filled. I wonder
> what's slowing my machine down so much for the PARSE & SUBSTR
> routines. Thanks for running my version.
>
> I just noticed that there's no decimal point in the READ: line.
> How long did it actually take?
>
Oops, the decimal should be after the first zero, so the result is
0.359000.
Rick
|
|
0
|
|
|
|
Reply
|
Rick
|
10/3/2009 6:50:37 PM
|
|
Swifty wrote:
> Rick McGuire wrote:
>> Parse: 0.016000
>> Substr: 0.016000
>> Read: 03590000
>>
>> The parse and read results are right up at the limits of the PC time
>> of day clock.
>
> If you were using my code unaltered, then your system is nearly 50 times
> faster than the fastest system I have access to. Would you mind telling
> me what it is, so I can suggest it to my manager when my PC renewal
> comes up (some time in 2010).
>
That was run on a ThinkPad 61P using ooRexx 4.0+ (and the debug version
at that).
Rick
|
|
0
|
|
|
|
Reply
|
Rick
|
10/3/2009 6:51:39 PM
|
|
Glenn Knickerbocker <NotR@bestweb.net> wrote:
> Is this necessary? Doesn't charin() return "up to length" characters,
> up to the end of the input stream? I'd think this should suffice:
>
> Do while chars(tmpfile) > 0
> block = charin(tmpfile,,blksize)
> ...
> End
What's the overhead in the chars(tmpfile) call each time around the loop?
Would it not be easier to use standartd EOF checking to discover when
there's no more data? Or look for a short block?
--
Jeremy C B Nicoll - my opinions are my own.
Email sent to my from-address will be deleted. Instead, please reply
to newsreplynnn@wingsandbeaks.org.uk replacing "nnn" by "284".
|
|
0
|
|
|
|
Reply
|
Jeremy
|
10/3/2009 8:52:36 PM
|
|
In Message-ID:<ioadnTPtZ9fpjlrXnZ2dnUVZ8oednZ2d@brightview.com>,
Swifty <steve.j.swift@gmail.com> wrote:
>Arthur T. wrote:
>> I'd be interested to see the numbers from your machines (with a
>> suitable LOOPS value). If you run it, remember to code a reasonable
>> name for TMPFILE.
>
>I'd only run that on a system that had a "Disk in Memory" filesystem
>(only the Office System).
>
>I presume you're working on the assumption that the write won't get
>committed to disk if you don't close the file, but I'm not sure how true
>that might be on a 600Mb block of data.
I wrote to a real disk. I had no assumptions; I just tried it.
And, my original run was with a 64MB file, so I expect it was
actually written and read.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
10/3/2009 9:08:00 PM
|
|
On Oct 3, 4:53=A0am, Swifty <steve.j.sw...@gmail.com> wrote:
> wolfgang.riedel wrote:
> > On 1 Oct, 09:06, markh <r...@users.sourceforge.net> wrote:
> > but even easier would be be:
> > l =3D length(data)
> > do while l > offset /* or length(data) > offset - something to
> > optimize */
> > =A0 =A0 parse var data block =3D(offset) data
> > =A0 =A0 l =3D l - offset /* not so in the length() case */
> > =A0 =A0 ...
> > end
> > block =3D data
> > ...
>
> That is the sort of code that I try to avoid, especially when
> length(data) is likely to start at something like 600000000.
>
> I know that the new value of "data" will be stored in the memory used by
> the old version (because it is always shorter), so the performance
> problem is nowhere near as bad as when you join the block using a
> similar technique. But I suspect that setting the variable "data" 146484
> times will slow things down.
Not necessarily true at all. It is patently false for all versions of
Object Rexx. That parse operation
creates two new string objects and the original is (potentially) made
available for garbage collection.
Rick
>
> --
> Steve Swifthttp://www.swiftys.org.uk/swifty.htmlhttp://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Rick
|
10/3/2009 10:27:48 PM
|
|
In <gemini.kqyhzn00mxatm026g@wingsandbeaks.org.uk.invalid>, on 10/03/2009
at 09:52 PM, Jeremy Nicoll - news posts
<jn.nntp.scrap004@wingsandbeaks.org.uk> said:
>What's the overhead in the chars(tmpfile) call each time around the
>loop? Would it not be easier to use standartd EOF checking to discover
>when there's no more data?
What is "standartd EOF checking" in REXX?
Lrf, gur dhrfgvba vf eurgbevpny.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
|
|
0
|
|
|
|
Reply
|
Shmuel
|
10/5/2009 1:29:25 AM
|
|
Rexx doesn't define i/o standards. Each platform has it's
own. Pc's don't even understand 'records' at the OS level
like CMS does, only data blocks.
Les (Change Arabic to Roman to email me)
Shmuel (Seymour J.) Metz wrote:
> In <gemini.kqyhzn00mxatm026g@wingsandbeaks.org.uk.invalid>, on 10/03/2009
> at 09:52 PM, Jeremy Nicoll - news posts
> <jn.nntp.scrap004@wingsandbeaks.org.uk> said:
>
>> What's the overhead in the chars(tmpfile) call each time around the
>> loop? Would it not be easier to use standartd EOF checking to discover
>> when there's no more data?
>
> What is "standartd EOF checking" in REXX?
>
> Lrf, gur dhrfgvba vf eurgbevpny.
>
|
|
0
|
|
|
|
Reply
|
LesK
|
10/5/2009 1:19:15 PM
|
|
LesK wrote:
> Rexx doesn't define i/o standards.
> Shmuel (Seymour J.) Metz wrote:
> > What is "standartd EOF checking" in REXX?
> > Lrf, gur dhrfgvba vf eurgbevpny.
I think the intended rhetorical answer was that CHARS()=0 *is* the
standard EOF check.
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
10/5/2009 8:43:23 PM
|
|
Glenn Knickerbocker wrote:
> I think the intended rhetorical answer was that CHARS()=0 *is* the
> standard EOF check.
Or "Signal on Notready". I'm not a fan of this because it leaves you
with "do forever" loops with no obvious exit mechanism.
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Swifty
|
10/6/2009 7:28:18 AM
|
|
Swifty wrote:
> Glenn Knickerbocker wrote:
>> I think the intended rhetorical answer was that CHARS()=0 *is* the
>> standard EOF check.
>
> Or "Signal on Notready". I'm not a fan of this because it leaves you
> with "do forever" loops with no obvious exit mechanism.
>
Well, a signal is an obvious exit mechanism, but if that really bothers
you, then use call on to set a loop terminating condition.
call on notready
atend = .false
do while \atend
-- read logic here
end
exit
notready:
atEnd = .true
This gives you an obvious exit mechamism on an eof...but the signal
mechanism is much cleaner, in my opinion.
Rick
|
|
0
|
|
|
|
Reply
|
Rick
|
10/6/2009 9:49:03 AM
|
|
Jeremy Nicoll - news posts <jn.nntp.scrap004@wingsandbeaks.org.uk> wrote:
> Would it not be easier to use standartd EOF checking to discover when
> there's no more data?
I meant using notready
--
Jeremy C B Nicoll - my opinions are my own.
Email sent to my from-address will be deleted. Instead, please reply
to newsreplynnn@wingsandbeaks.org.uk replacing "nnn" by "284".
|
|
0
|
|
|
|
Reply
|
Jeremy
|
10/6/2009 10:54:36 AM
|
|
Rick McGuire wrote:
> This gives you an obvious exit mechamism on an eof...but the signal
> mechanism is much cleaner, in my opinion.
Until your loop gets put inside another loop!
Do i = 1 to file.0
Signal on Notready name Thisloop
Do forever
... charin(file.i ...
End
Thisloop:
Say 'This works the FIRST time!'
End
Actually, in the case at hand, how would you ever even get the last
incomplete block this way? NOTREADY is raised as soon as you read it,
and it doesn't have a chance to be saved anywhere.
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
10/6/2009 8:23:30 PM
|
|
Glenn Knickerbocker wrote:
> Rick McGuire wrote:
>> This gives you an obvious exit mechamism on an eof...but the signal
>> mechanism is much cleaner, in my opinion.
>
> Until your loop gets put inside another loop!
>
> Do i = 1 to file.0
> Signal on Notready name Thisloop
> Do forever
> ... charin(file.i ...
> End
> Thisloop:
> Say 'This works the FIRST time!'
> End
>
> Actually, in the case at hand, how would you ever even get the last
> incomplete block this way? NOTREADY is raised as soon as you read it,
> and it doesn't have a chance to be saved anywhere.
>
> �R
NOTREADY is not raised until end-of-clause, as is any condition where
CALL ON is supported. The assignment has a chance to complete as a result.
Rick
|
|
0
|
|
|
|
Reply
|
Rick
|
10/7/2009 9:30:17 AM
|
|
In <4ac9f259$0$4978$9a6e19ea@unlimited.newshosting.com>, on 10/05/2009
at 09:19 AM, LesK <5mre20@tampabay.rr.com> said:
>Rexx doesn't define i/o standards.
ROTF,LMAO. Please tell that to ANSI.
>Pc's don't even understand 'records' at the OS level
>like CMS does, only data blocks.
K3wl! How is that relevant? Every REXX that I've used on a PC has
implimented, e.g., chars, lines and NOTREADY.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
|
|
0
|
|
|
|
Reply
|
Shmuel
|
10/7/2009 3:23:44 PM
|
|
In <4ACA5A6B.90F611F4@bestweb.net>, on 10/05/2009
at 04:43 PM, Glenn Knickerbocker <NotR@bestweb.net> said:
>I think the intended rhetorical answer was that CHARS()=0 *is* the
>standard EOF check.
In ANSI Rexx chars and lines are the way to go, but in older Rexx
implementations you may have to rely on NOTREADY, which can be signalled
for other reasons than EOF.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
|
|
0
|
|
|
|
Reply
|
Shmuel
|
10/7/2009 3:26:08 PM
|
|
Rick McGuire wrote:
> NOTREADY is not raised until end-of-clause, as is any condition where
> CALL ON is supported. The assignment has a chance to complete as a result.
That's only true of CALL ON, not SIGNAL ON, right? I don't see how you
would handle the last incomplete block when using SIGNAL ON NOTREADY.
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
10/7/2009 3:32:59 PM
|
|
Shmuel (Seymour J.) Metz wrote:
> In <4ac9f259$0$4978$9a6e19ea@unlimited.newshosting.com>, on 10/05/2009
> at 09:19 AM, LesK <5mre20@tampabay.rr.com> said:
>
>> Rexx doesn't define i/o standards.
>
> ROTF,LMAO. Please tell that to ANSI.
Oops! Sorry, I must have had a flashback to my VM days of
Rex and before ANSI.
>
>> Pc's don't even understand 'records' at the OS level
>> like CMS does, only data blocks.
>
> K3wl! How is that relevant? Every REXX that I've used on a PC has
> implimented, e.g., chars, lines and NOTREADY.
Perhaps, but they aren't they arbitrary *conventions* for
lines? They aren't defined by the OS, like they are for CMS.
>
|
|
0
|
|
|
|
Reply
|
LesK
|
10/8/2009 10:12:28 PM
|
|
In <4ace63cd$0$5648$9a6e19ea@unlimited.newshosting.com>, on 10/08/2009
at 06:12 PM, LesK <5mre20@tampabay.rr.com> said:
>Perhaps, but they aren't they arbitrary *conventions* for
>lines? They aren't defined by the OS, like they are for CMS.
But still referred to in the ANSI standard as well as all current PC
implementations.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
|
|
0
|
|
|
|
Reply
|
Shmuel
|
10/9/2009 6:53:29 PM
|
|
|
44 Replies
236 Views
(page loaded in 0.796 seconds)
|