Subject: Re: [Q] fast integer array sending

From: "Paul A. Houle" <[email-masked]>
Date: Tue, 10 Mar 1998 08:52:59 -0500

A lot of people around here seem willing to throw in the towel
mighty fast.

    JDK 1.1's object serialization is **FAST**,  orders of magnitude
faster than pure-java attempts
to serialize objects.  I have a program which reads a few million
doubles from a disk file;  when the
file was full of ascii-formatted numbers it took something like 170
seconds to read it all (on a Linux box with no JIT).  I think it takes
about 3 seconds to read a million serialized doubles.  Much of that is
disk
I/O overhead.

    I couldn't live without serialization these days.  Is anyone out
here using RMI seriously for scientific calculations?  Does anybody have
performance numbers?

    But really,  I can't complain about doing scientific calculations in
Java.  Yes,  if you're doing Grand Challenge work it might not have the
raw speed of hand-optimized assembly code,  but for ordinary science I
don't have any problems.  Just yesterday I stored a billion voxels in
core;  it took me just minutes to parallelize my calculations across our
SMP machine with nearly ideal speedup.

    Lately I found something which makes Java and Python both about ten
times more fun than they were before.  JPython is a pure java
implementation of Python -- it compiles Python to Java bytecodes,  so
with JIT it's about as fast as Python 1.4.  You can script java objects
seamlessly in JPython and use JPython to subclass Java classes.  Works
with Java Beans.  It rocks;  I'm never going to program the same way
again.  You can grab it from http://www.python.org/jpython.

---

From: Brian Van Straalen <[email-masked]>
Date: Tue, 10 Mar 1998 10:51:34 -0500 (EST)

Well, I threw in the towel (temporarily) before serialization
came along.  But I still program and run some number
crunching in java, and it is still slower.  How
much slower?  well, with JIT (HP's, it kicks) I'm
still about 50% off the mark.  That's fine for
academic work, but you're never going to sell a
commercial scientific computing application with
those kind of numbers.  It wasn't fast (I'm on year
three now), and it isn't complete.

  My gripe is: Sun decided it was important to speed
up communication and IO, so Sun built it for you.  When
Sun decides to build cache exploiting pipeline operations,
or a BLAS, then you will get that too.  I don't see these
things happening in '98, so I'm withholding my love.

Brian

---

From: Brian Van Straalen <[email-masked]>
Date: Mon, 9 Mar 1998 23:50:41 -0500 (EST)

Well, for my work, I've used the a byte array buffer.  You create
a DataOutputStream from a ByteArrayOutputStream object.  Set up
the byte array to be big enough to hold your thousand ints
(be careful here, since writing out int to a stream is 
more data that just the number of bytes in an int).

Fill the array locally with the loop you already have
coded (ie. use the DataOutputStream object...which knows
the proper encoding).

when you're ready to send, then do this

ByteArrayOutputStream bytestream(.....)
DataOutputStream localBytes(bytestream);
// loop to fill in localBytes....
....
//
DataOutputStream thisOneAttachedToSocket(.....)
byte[] buff = bytestream.toByteArray();
// now send the data off in one big write....
thisOneAttachedToSocket.write(buff, 0, buff.length());

that sends them all out in one write (which gets
buffered also, but since write doesn't block the
thread, your program is free to run, and the IO
system can perform more optimized data transfer with
a nice big chunk...at least the better coded
Java implementations will exploit this construct).

Later, I wrote my own versions of the ByteArrayOutputStream
to prevent the data copying and memory fragmentation
that occurs with the default implementation.  If you
have complete knowledge of the nature of the data
that is getting buffered (size, etc.) you can do
much better than the default buffering for socket
IO.  I managed to get near real time program
synchronization across multiple VMs with this machinery.

The real performance improvement is not available
to the Java user: (knowing how the int[] is
stored, copying the bytes, and firing them
into the socket).  This is theoretically possible,
since Java has unified the interpretation of
byte, int, double, etc etc., but the smart user
is not given sufficient access to make this
kind of optimization.  Pure Java means "Wait
until Sun decides to build it for you"

There are further improvements that could be made,
but I have more important things to do these days
than fix java.

I also used this type of coding style for my own version
of object serialization (I wrote it back before any spec
showed up and there was lots of talk, but no action)

  While Sun choses to spend its energies these days
on embedded technology and such, I've gone back to
C++ to get the scientific computing power I need.  I've
written them my thoughts on this issue, and recieved
enough replies (exactly zero replies) that I feel 
comfortable taking this unkind slight at their expense.

Hope you learn a lot using Java.  Don't let my
bitterness stop you from using the language (It 
could take years off your coding time). It's just
that scientific computing is not something 
Java is doing well these days.  I'll probably
get back to Java in a year or so to see if things
have changed...I do like to program in it.

PS.

before anyone asks, I will not be attending JavaOne
this year.

===============================================================
Brian Van Straalen              Software Engineer/Mathematician
Beam Technologies Inc.          Ithaca NY.
===============================================================

> 	Hi! everyone.
> 	I am writing a parallel and distributed program with java.
> 	In this program, one application on web server machine should communicate with many 
> 	applets which are downloaded from this web server machine and executed on the 
> 	other machines. The application opens socket connection and waits for
> 	any applet's request. When an applet sends request, the application and an applet 
> 	can communicate via socket.
> 	I used DataInputStream class and DataOutputStream class to write and read socket.
> 	I would like to send big integer array from application to applet and from applet to application.
> 	So I used DataInputStream and DataOutputStream class and its member method writeInt(int).
> 	But it is very slow to send one integer after another. 
> 	If I want to send 1000 integer array, I have used 
> 	for (i=0; i<1000; ++i)
> 	  writeInt(a[i]);
> 
> 	I think there might be more powerful method to send integer array via socket.
> 	But I don't know what the method is.
> 	If you know it, please let me know it. It will be very much help to my research.
> 	sincerely yours.
> 
> 
> 	Hye-Seon Maeng 	([email-masked])
> 
> 	Parallel Processing System Lab.
> 	Computer Science Dept.
> 	Yonsei University Seoul Korea
>