I respectfully express my opinion without intending to badmouth anyone.
I believe that benchmarking the performance of reading a large file is
not an artificial test but rather a real-world use case that we
encounter regularly. It is no secret that REXX on z/OS can be slow. In
fact, one of my colleagues who worked on the IBM File Manager product,
which incorporates REXX scripting, developed their own subset of REXX
because the performance of the TSO REXX interpreter did not meet their
objectives.
On 28/2/23 22:38, Rony G. Flatscher wrote:
On 28.02.2023 13:44, David Crayford wrote:
ooRexx has two main issues: its a superset of REXX, which is a subpar
programming language, and it consumes a lot of CPU resources. Each
language clause in ooRexx is a C++ object that invokes dynamic
dispatch whenever it's executed. Unlike most other sensible
programming languages, which compile to bytecode and use a virtual
machine, ooRexx does not. When I benchmarked OoRexx against Lua, I
was surprised to find that it was almost 100 times slower. I used
valgrind to profile ooRexx's performance and discovered that most of
the time was spent allocating and marking objects for garbage
collection. These objects were language metadata used by the
interpreter. ooRexx is an example of how not to implement a language
interpreter in C++.
A lot of badmouthing and red herrings here (again), comparing apples
with oranges (again). Totally ignoring what has been discussed and
concluded a year ago, so no reliability on you.
Last year there was a discussion with the subject that over time got
superceeded with mailings of different focuses:
- "Top 8 Reasons for using Python instead of REXX for z/OS", which
then ended in the subject:
- "Speedy, speedier, speedest (Re: Ad message paradigm (Re: Ad NetRexx
(Re: Ad programming features (Re: ... Re: Top 8 Reasons for using
Python instead of REXX for z/OS"
In that thread I demonstrated a little ooRexx program that did beat
your impertinent "test program" that you implemented in C++, Lua and
Python last year (still wondering why you did not implement that
simple benchmark in Assembler and show those figures). After learning
about that ooRexx program that actually performed faster than C++ (Lua
and Python of course as well) you preferred to stop that thread of
discussion about a year ago. Now you are back, maybe speculating
everyone forgot about it?
The purpose of your "test program" was quite obviously to make Rexx
and ooRexx look as bad as possible. The same intent as your current
message in your posting like: "ooRexx is an example of how not to
implement a language interpreter in C+." (which is nonsense).
Your artificial "test/benchmark program" that let C++, Lua, Python
shine at first and make Rexx/ooRexx look quite bad was designed
exactly for that purpose: let strictly typed and compiled languages be
way ahead of dynamically typed and interpreted languages, so:
- create an array of size of ten million (sic!) of (primitive) type long
- fill the array in a loop and assign each index the result of taking
the index value (an int being cast to long) to the square
- go through that array and get the largest stored long value and
display it
BTW, who has a real need for such programs in her/his daily life here?
(In this community who would really come up with the idea of
implementing such a task in Rexx/ooRexx and not in Assembler if a real
need existed?)
So this everyday (not!) "benchmark" is designed to make dynamically
typed and interpreted languages look as bad as possible compared to
strictly typed, compiled languages! It would be like comparing number
crunching Rexx/ooRexx programs with the same programs implemented in
Assembler and concluding Assembler is much better in general and
forego Rexx/ooRexx (and ignoring the many other use cases in which
Rexx/ooRexx is much better than Assembler can possibly be; any
language has its strengths and its weaknesses, of course, including
C++, Lua, Python, ...)!
It is an artificial test program. Still, it is possible to beat
strictly typed, compiled languages with dynamically typed, interpreted
languages like ooRexx as demonstrated last year in this mailing list!
You just need to use your brain and the infrastructure that is
available to you.
The technique has been rather simple: like it is the case with
external function packages for Rexx/ooRexx (to e.g. interact with
system services, RDBMS etc.) look for a package/environment that is
strictly typed and compiled and which one can take advantage of. In
this particular show case I picked Java/NetRexx (NetRexx compiles to
Java byte code, so one can write with the Rexx syntax genuinely Java
programs; NetRexx is rather easy to learn for Rexx-savvy programmers)
as an external package.
BTW, in the meantime I added the respective ooRexx examples to the
ooRexx-Java bridge named "BSF4ooRexx850" (makes all Java class
libraries directly available to ooRexx and camouflages Java as ooRexx,
i.e. making Java objects understand ooRexx messages, in general
allowing for ignoring strict casing and much more) to demonstrate how
to exploit Java/NetRexx for this kind of use case from ooRexx.
Here the ooRexx program exploiting Java
("samples/4-601_compileAndRunEmbeddedJava1.rxj") for carrying out that
stupid task, the Java code is given in the resource directive (allows
for placing and retrieving any text in an ooRexx program) named
"squares.java":
--- cut ---
signal on syntax /* in case a condition gets raised */
/* A compiled Java program has a static main method that expects an
array of type String (representing supplied command line
arguments). */
say "ooRexx: use embedded Java program: fetch, compile & run it ..."
d1=.dateTime~new /* for timings */
clzSquares=bsf.compile("squares", .resources~squares.java, "Java")
d2=.dateTime~new /* for timings */
clzSquares~main(.nil) /* run the Java program */
d3=.dateTime~new /* for timings */
say "compiling Java program:" d2-d1 /* show duration */
say "running Java program :" d3-d2 /* show duration */
exit
syntax: /* in case of an error */
co=condition('object') /* get all condition information */
say ppJavaExceptionChain(co) /* show Java exception chain */
say "---> this program needs ooRexx 5.0 or later"
raise propagate /* let ooRexx interpreter handle it */
::RESOURCE squares.java /* Java source code */
/* Java: squares.java */
import java.util.Arrays;
public class squares
{
public static void main (String args[])
{
int items = 10000000;
long [] s = new long [items];
for (int i=1; i<=items; i++)
{
long n=i;
s[i-1] = n * n;
}
System.out.println(Arrays.stream(s).max().getAsLong());
}
}
::END
::requires BSF.CLS /* get full bidirectional Java support */
--- cut ---
Here that ooRexx program exploiting NetRexx
("samples/4-600_compileAndRunEmbeddedNetRexx1.rxj") for carrying out
that stupid task which allows one to compare the Java code with the
equivalent NetRexx code which is much simpler than the Java code; the
NetRexx code is given in the resource directive (allows for placing
and retrieving any text in an ooRexx program) named "squares.nrx":
--- cut ---
signal on syntax /* in case a condition gets raised */
/* A compiled NetRexx program has a static main method that expects an
array of type String (representing supplied command line
arguments). */
say "ooRexx: use embedded NetRexx program: fetch, compile & run it
..."
d1=.dateTime~new /* for timings */
clzSquares=bsf.compile("squares", .resources~squares.nrx, "NetRexx")
d2=.dateTime~new /* for timings */
clzSquares~main(.nil) /* run the NetRexx program */
d3=.dateTime~new /* for timings */
say "compiling NetRexx program:" d2-d1 /* show duration */
say "running NetRexx program :" d3-d2 /* show duration */
exit
syntax: /* in case of an error */
co=condition('object') /* get all condition information */
say ppJavaExceptionChain(co) /* show Java exception chain */
say "---> this program needs NetRexx and ooRexx 5.0 or later"
raise propagate /* let ooRexx interpreter handle it */
::RESOURCE squares.nrx /* NetRexx source code */
/* NetRexx: squares.nrx */
options binary /* in this case we want speed */
items = 10000000
s = long[items] /* define a Java array of type long */
loop i=1 to items
n=long i /* for multiplication we want to use long */
s[i-1] = n * n
end
/* use java.util.Arrays' stream() (introduced with Java 8) */
say Arrays.stream(s).max.getAsLong
::END
::requires BSF.CLS /* get full bidirectional Java support */
--- cut ---
These ooRexx samples demonstrate in general how one can create any
logic in Java/NetRexx (having the source code in the ooRexx program),
compile it and then use it right away from the very same ooRexx
program. Also, this solution allows for letting C++, Lua and Python
bite even more dust if not only going after the max values of that
abmysal artificial array of longs, but in addition to calculate the
average, count, min and sum (cf. the samples BSF4ooRexx850 samples in
"samples/4-610_compileAndUseEmbeddedNetRexx2.rxj",
"samples/4-611_compileAndUseEmbeddedJava2.rxj")! :)
One quite nice thing about ooRexx and BSF4ooRexx850 is: no matter
whether you write the programs on your Windows, your macOS or your
Linux PC, you can take those programs and run them on any of the other
operating systems including Linux on IBM Z for which ooRexx 5 [1] and
BSF4ooRexx850 [2] ports exist!
--
Usually one would use specilaized libraries and function packages for
any features for which specialized knowledge has been developed and
used for implementations over many years, e.g. like interfacing with
RDBMS, data analysis packages etc. There are plentiful and powerful
Java packages out there which you can immediately take advantage of
with ooRexx, and easily so!
As ooRexx is CMake based it can be easily compiled by yourself for
your platform (and of course to Linux on IBM Z) at any time.
---
Last year we also discussed about the great features the message based
nature (after SmallTalk [3]) of ooRexx offers to programmers, e.g.
making it very easy (saving a lot of time!) for the programmer to
interact with e.g. OLE or Java or DBus and the like.
C++, Lua and Python by contrast totally lack such an important
feature, that Alan Kay on Wikipedia [4] characterizes as follows:
I'm sorry that I long ago coined the term "objects" for this topic
because it gets many people to focus on the lesser idea. The big idea
is "messaging <https://en.wikipedia.org/wiki/Message_passing>".
This "bigger idea" is something that you seem to not have understood
and have been ignoring.
By contrast ooRexx implements that bigger idea (being itself
implemetned in C++) opening up new opportunities to Rexx programmers.
---
ooRexx is Rexx and adds object-orientation and the message paradigm to
the language. Everyone here with Rexx skills can immediately take
advantage of ooRexx.
BSF4ooRexx850 bridges ooRexx with Java, effectively camouflaging Java
objects as ooRexx objects (!), making it a breeze to interact with
Java. (BTW, BSF4ooRexx850 also allows for implementing abstract Java
classes in ooRexx classes, believe it or not! This feature allows for
dealing with Java callbacks in Rexx code, which is much simpler.)
---rony
[1] ooRexx 5.0:
<https://sourceforge.net/projects/oorexx/files/oorexx/5.0.0/>
[2] BSF4ooRexx850:
<https://sourceforge.net/projects/bsf4oorexx/files/beta/20221004/>
included in the installation package
"BSF4ooRexx_install_v850-20230109-beta.zip"
(Dubbed a beta, however quality has been of release; this version
takes advantage of ooRexx 5.0 features, e.g. allowing to dynamically
add Rexx command handlers that are implemented in Java! It comes with
a showcase, a Rexx command handler named JDOR - "Java2D for ooRexx".
Here the JDOR Rexx commands with a simple example at the beginning:
<https://wi.wu.ac.at/rgf/rexx/misc/jdor_doc.tmp/jdor_doc.html>)
[3] SmallTalk: <https://en.wikipedia.org/wiki/Smalltalk>
[4] Alan Kay: <https://en.wikipedia.org/wiki/Alan_Kay>
On 28/2/23 20:28, Seymour J Metz wrote:
What about Java? How well does JIT work?
The gold standard for REXX is ooRexx, but IBM has not seen fit to
integrate it into z/OS or z/VM.
However, for off the shelf package libraries, Perl and Python are
admittedly ahead of REXX. What are the Python and Ruby equivalents
of CPAN?
I've found extending REXX for CMS and TSO to be easy, although
admittedly assembler is mothers' milk to me and I didn't have to
deal with LE issues.
--
Shmuel (Seymour J.) Metz
http://mason.gmu.edu/~smetz3
________________________________________
From: IBM Mainframe Discussion List [[email protected]] on
behalf of David Crayford [[email protected]]
Sent: Tuesday, February 28, 2023 12:47 AM
To: [email protected]
Subject: Re: zOSMF and zOWE for non-mainframers
On 25/2/23 01:23, Farley, Peter wrote:
Python on the mainframe is pretty good, but still can't beat out
Rexx in performance even when the Rex script needs to use BPXWUNIX
and friends to access z/OS Unix file systems,
I have conducted a series of benchtests, and the results suggest that
REXX is not as fast as Python. In my testing, I compare the performance
of C, Lua, Python, and REXX, and the results are clear: C is the
fastest, followed by Lua, which is within an order of magnitude of C.
Python comes next, within an order of magnitude of Lua, and REXX
consistently performs the poorest. In addition to the performance
factor, the vast Python ecosystem compared to the limited options
available for REXX also make it an easy decision. Python is also
simpler
to extend with packages, while REXX requires more effort and
potentially
complex steps, such as using modern libraries that require Language
Environment (LE).
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN