Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.project
16 changes: 16 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,19 @@ http://code.google.com/p/stdf4j
CONTACT

tragicphantom@gmail.com

---

performance optimize:
1. change the ByteArray to singleton
2. new Float/Double to Float/Double.valueOf
3. change the "new String(cbuf, 0, length).intern()" to new
String(data, offset, length, ASCII)
4. change the Arrays.copyOfRange to System.arraycopy

one 1.2G stdf file need 24s with "record.getData()" called,
after optimized, the time is 9s(test env, Windows 7, Java 1.8)

CONTACT

lantianjialiang@126.com
4 changes: 4 additions & 0 deletions lib/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.classpath
.project
target
.settings
33 changes: 23 additions & 10 deletions lib/src/main/java/com/tragicphantom/stdf/Record.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,30 @@

import java.text.ParseException;

import com.tragicphantom.stdf.util.ByteArray;

public class Record{
private RecordDescriptor desc;
private int pos;
private byte [] data;
private ByteOrder byteOrder;
// private ByteOrder byteOrder;
private RecordData rd;

public Record(RecordDescriptor desc, int pos,
byte [] data, ByteOrder byteOrder){
this.desc = desc;
this.pos = pos;
this.data = data;
this.byteOrder = byteOrder;
this.rd = null;
}
// public Record(RecordDescriptor desc, int pos,
// byte [] data, ByteOrder byteOrder){
// this.desc = desc;
// this.pos = pos;
// this.data = data;
// this.byteOrder = byteOrder;
// this.rd = null;
// }

public Record(RecordDescriptor desc, int pos, byte[] data) {
this.desc = desc;
this.pos = pos;
this.data = data;
this.rd = null;
}

public Record(RecordDescriptor desc, RecordData rd){
this.desc = desc;
Expand All @@ -54,7 +63,7 @@ public int getPosition(){

public RecordData getData() throws ParseException{
if(rd == null)
rd = desc.parse(pos, data, byteOrder);
rd = desc.parse(pos, data);
return rd;
}

Expand All @@ -66,4 +75,8 @@ public String toString(){
return "(null)";
}
}

public int getDataLength() {
return data.length;
}
}
71 changes: 46 additions & 25 deletions lib/src/main/java/com/tragicphantom/stdf/RecordDataParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
package com.tragicphantom.stdf;

import java.util.Arrays;

import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;

import java.nio.charset.Charset;
import java.text.ParseException;

import com.tragicphantom.stdf.util.ByteArray;
Expand All @@ -33,13 +33,14 @@ public class RecordDataParser{
private ByteArray byteArray;
private int available;
private int offset;

private static byte[] sharedBytes = new byte[10];

public RecordDataParser(RecordDescriptor desc, int pos, byte [] data,
ByteOrder byteOrder){
public RecordDataParser(RecordDescriptor desc, int pos, byte [] data){
this.desc = desc;
this.pos = pos;
this.data = data;
this.byteArray = new ByteArray(byteOrder);
this.byteArray = ByteArray.getInstance();
this.available = data.length;
this.offset = 0;
}
Expand All @@ -50,16 +51,16 @@ public RecordData parse() throws ParseException{

for(Field field : desc.getFields()){
Object value = null;
if(available > 0 && validField(field, fieldList)){
if(available > 0 /*&& validField(field, fieldList) */ ){
//System.err.println(field.getName() + " => " + field.getType() + " => " + field.getLength());
value = readField(field.getType(),
field.getLength(),
field.getLengthFieldIndex(),
field.getArrayType(),
field.getArraySizeFieldIndex(),
fieldList);
}
else{
} else {
char type = field.getType();
if(type == 'U' || type == 'I')
value = Integer.valueOf(0);
Expand Down Expand Up @@ -131,17 +132,18 @@ else if(type == 'S')
else // type == 'C'
return readString(readUnsignedInt(1));
case 'R':
if(length == 4)
return new Float(byteArray.toFloat(getBytes(4)));
else
return new Double(byteArray.toDouble(getBytes(8)));
if(length == 4) {
return Float.valueOf((byteArray.toFloat(getBytes(4))));
}

return Double.valueOf(byteArray.toDouble(getBytes(8)));
case 'V':
return readVariableTypeList();
case 'k':
return readArray(arrayType, arraySizeFieldIndex, lengthFieldIndex,
length, fields, false);
}

throw new ParseException("Invalid type code: " + type, pos);
}

Expand Down Expand Up @@ -248,6 +250,8 @@ protected long getFieldSize(Object field){
return size;
}

private static final Charset ASCII = Charset.forName( "US-ASCII" );

protected String readString(int length){
/**
* The following is a trick from Trevor Pounds:
Expand All @@ -260,15 +264,28 @@ protected String readString(int length){
* but from my testing this custom logic outperforms the internal charset
* encoding algorithm (i.e. -agentlib:hprof=cpu=times).
*/
final byte[] bbuf = getBytes(length);

length = bbuf.length; // adjust according to how much data actually read

char [] cbuf = new char[length];
for(int i = 0; i < length; i++)
cbuf[i] = (char) (0xFF & bbuf[i]);

return new String(cbuf, 0, length).intern();
// final byte[] bbuf = getBytes(length);
//
// length = bbuf.length; // adjust according to how much data actually read
//
// char [] cbuf = new char[length];
// for(int i = 0; i < length; i++)
// cbuf[i] = (char) (0xFF & bbuf[i]);
//
// return new String(cbuf, 0, length).intern();

// final byte[] bbuf = getBytes(length);
// return new String(bbuf);
available -= length;
if (available < 0) {
length += available;
available = 0;
}

String tmp = new String(data, offset, length, ASCII);
offset += length;

return tmp;
}

protected int readSigned(int length){
Expand Down Expand Up @@ -304,9 +321,13 @@ protected byte[] getBytes(int numBytes){
available = 0;
}

byte[] bytes = Arrays.copyOfRange(data, offset, offset + numBytes);
offset += numBytes;
// byte[] bytes = Arrays.copyOfRange(data, offset, offset + numBytes);
// offset += numBytes;

return bytes;
//TODO file sharedBytes to 0
System.arraycopy(data, offset, sharedBytes, 0, numBytes);
offset += numBytes;

return sharedBytes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public boolean contains(String name){
return indexes.containsKey(name);
}

public RecordData parse(int pos, byte [] bytes, ByteOrder byteOrder) throws ParseException{
return new RecordDataParser(this, pos, bytes, byteOrder).parse();
public RecordData parse(int pos, byte [] bytes) throws ParseException{
RecordDataParser parser = new RecordDataParser(this, pos, bytes);
return parser.parse();
}
}
4 changes: 3 additions & 1 deletion lib/src/main/java/com/tragicphantom/stdf/RecordVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
**/
package com.tragicphantom.stdf;

import java.text.ParseException;

public interface RecordVisitor{
public void beforeFile();
public void afterFile();
public void handleRecord(Record record);
public void handleRecord(Record record) throws ParseException;
}
10 changes: 5 additions & 5 deletions lib/src/main/java/com/tragicphantom/stdf/STDFReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class STDFReader{
private InputStream stream = null;
private int available = 0;
private int totalBytes = 0;
private ByteArray byteArray = new ByteArray();
private ByteArray byteArray = ByteArray.getInstance();
private boolean errorOnUnknown = true;

public STDFReader(String fileName) throws FileNotFoundException, IOException{
Expand All @@ -57,7 +57,7 @@ public STDFReader(File file) throws FileNotFoundException, IOException{
}

public STDFReader(InputStream stream) throws IOException{
InputStream bufis = new BufferedInputStream(stream);
InputStream bufis = new BufferedInputStream(stream, 8192 * 1);
bufis.mark(2);
int header = ((bufis.read() & 0xFF) << 8) + (bufis.read() & 0xFF);
bufis.reset();
Expand Down Expand Up @@ -118,7 +118,7 @@ record = readRecord(header, records);
visitor.handleRecord(record);
}
}
catch(IOException e){
catch(IOException | ParseException e){
// Ignore
//e.printStackTrace();
}
Expand Down Expand Up @@ -151,8 +151,8 @@ protected Record readRecord(Header header,
if(records.containsKey(header.getRecordType())){
record = new Record(records.get(header.getRecordType()),
totalBytes,
getBytes(header.getLength()),
byteArray.getByteOrder());
getBytes(header.getLength()) );
// byteArray.getByteOrder());
}
else{
// this may just be a user-defined record type not specified
Expand Down
44 changes: 27 additions & 17 deletions lib/src/main/java/com/tragicphantom/stdf/util/ByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,17 @@
*/
public class ByteArray
{
private ByteOrder byteOrder = ByteOrder.nativeOrder();

public ByteArray(){
private static ByteOrder staticByteOrder = ByteOrder.nativeOrder();

private ByteOrder byteOrder = ByteOrder.nativeOrder();

private static ByteArray array = new ByteArray(staticByteOrder);

public static ByteArray getInstance() {
return array;
}

private ByteArray(){
}

public ByteArray(ByteOrder byteOrder){
Expand Down Expand Up @@ -61,14 +69,16 @@ public final char toChar(final byte[] bytes){
return (char) ((bytes[0] & 0xFF) + ((bytes[1] & 0xFF) << 8));
}

public final double toDouble(final byte[] bytes)
{ return Double.longBitsToDouble(toLong(bytes)); }
public final double toDouble(final byte[] bytes) {
//TODO below maybe wrong for shared bytes array
return Double.longBitsToDouble(toLong(bytes));
}

public final float toFloat(final byte[] bytes)
{ return Float.intBitsToFloat(toInt(bytes)); }
{ return Float.intBitsToFloat(toInt(bytes, 4)); }

public final int toInt(final byte[] bytes){
if(bytes.length == 4){
public final int toInt(final byte[] bytes, int length){
if(length == 4){
if(byteOrder == ByteOrder.BIG_ENDIAN)
return (int) (((bytes[0] & 0xFF) << 24) + ((bytes[1] & 0xFF) << 16) +
((bytes[2] & 0xFF) << 8) + (bytes[3] & 0xFF));
Expand All @@ -83,12 +93,12 @@ public final int toInt(final byte[] bytes){
public int toSigned(final byte[] bytes, int length){
int value = 0;

if(length == 1 && bytes.length >= 1)
if(length == 1)
value = (int)bytes[0];
else if(length == 2 && bytes.length >= 2)
value = (int)toShort(bytes);
else if(length == 2)
value = (int)toShort(bytes, length);
else
value = toInt(bytes);
value = toInt(bytes, length);

return value;
}
Expand All @@ -103,11 +113,11 @@ public long toUnsigned(final byte[] bytes, int length){
value = b < 0 ? ((long)(b & 0x7F) | 0x80) : b;
}
else if(length == 2 && bytes.length >= 2){
short s = toShort(bytes);
short s = toShort(bytes, length);
value = s < 0 ? ((long)(s & 0x7FFF) | 0x8000) : s;
}
else{
int i = toInt(bytes);
int i = toInt(bytes, length);
value = i < 0 ? ((long)(i & 0x7FFFFFFFL) | 0x80000000L) : i;
}

Expand All @@ -122,7 +132,7 @@ public int toUnsignedInt(final byte[] bytes, int length){
value = b < 0 ? ((b & 0x7F) | 0x80) : b;
}
else if(length == 2 && bytes.length >= 2){
short s = toShort(bytes);
short s = toShort(bytes, length);
value = s < 0 ? ((s & 0x7FFF) | 0x8000) : s;
}

Expand All @@ -146,8 +156,8 @@ public final long toLong(final byte[] bytes){
return 0;
}

public final short toShort(final byte[] bytes){
if(bytes.length == 2){
public final short toShort(final byte[] bytes, int length){
if(length == 2){
if(byteOrder == ByteOrder.BIG_ENDIAN)
return (short) ((bytes[1] & 0xFF) + ((bytes[0] & 0xFF) << 8));
else
Expand Down
Loading