no IO, Logging, and Console Output

- 186 - Foo lazily initialized 20 7 We have lost out on the writes because of the added complexity, but improved the reads considerably. The cost of the Foo.convert method has not been factored in, but the strategy illustrated here is for cases where you need to run only that convert method on a small subset of the deserialized objects, and so the extra overhead should be small. This technique works well when transferring large groups of objects across a network. For the case in which you need only a few objects out of many serialized objects that have been stored on disk, another strategy is available that is even more efficient. The strategy uses techniques similar to the example just shown. One file the data file holds the serialized objects. A second file the index file holds the offset of the starting byte of each serialized object in the first file. For serializing, the only difference to the example is that when writing out the objects, the full DataOutputStream.written instance variable is added to the index file as the writeExternal method is entered, instead of writing the difference between successive values of DataOutputStream.written . A moments thought should convince you that this provides the byte offset into the data file. With this technique, deserializing is straightforward. You enter the index file and skip to the correct index for the object you want in the data file e.g., for the object at array index 54, skip 54 × 4 = 216 bytes from the start of the index file. The serialized int at that location holds the byte offset into the data file, so you deserialize that int . Then you enter the data file, skipping to the specified offset, and deserialize the object there. This is also the first step in building your own database: the next steps are normally to waste time and effort before realizing that you can more easily buy a database that does most of what you want. This index file-plus-data file strategy works best if you leave the two files open and skip around the files, rather than repeatedly opening and closing the files every time you want to deserialize an object. The strategy illustrated in this paragraph does not work as well for transferring serialized objects across a network. For network transfers, a better strategy is to limit the objects being transferred to only those that are needed. [15] Table 8-3 shows the tunings of the serialization tests, normalized to the JDK 1.2 standard serialization test. Each entry is a pair giving writeread timings. The test name in brackets refers to the method name executed in the tuning.io.SerializationTest class. [15] You could transfer index files across the network, then use those index files to precisely identify the objects required and limit transfers to only those identified objects. Table 8-3, Timings in writeread pairs of the Serialization Tests with Various VMs 1.2 1.2 no JIT 1.3 HotSpot 1.0 Standard serialization test1a 100 175 393 366 137 137 127 219 Customized writereadObject in Foo and Bar test2a 125 148 326 321 148 161 160 198 Customized writereadObject in Foo handling Bar test3a 31 59 113 162 47 63 54 83 Foo made Externalizable, using last methods renamed test4a 28 46 104 154 32 47 33 50 Foo as last test, but writeread called directly in test test4c 8 36 35 106 6 21 7 26 Foo lazily initialized test5a 20 7 54 12 19 4 14 11 - 187 -

8.5 Clustering Objects and Counting IO Operations