Skip to content
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
33bb73a
IGNITE-13856 changing writeString method. String.getBytes() is called…
aries-3 Dec 15, 2020
99122ef
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
b9bf2e5
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
d633d66
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
5904642
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
116c61d
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
b8dcc0f
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
2c7adf0
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 16, 2020
17fd38e
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 17, 2020
55e0663
IGNITE-13856 DirectByteBufferStreamImplV2.writeString method is chang…
aries-3 Dec 17, 2020
2dcf0ee
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 17, 2020
542385c
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 17, 2020
90e7e6c
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 17, 2020
ed6d89f
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 21, 2020
f5225e4
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 21, 2020
bf57acb
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 21, 2020
da5c77b
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 21, 2020
ad5a952
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 22, 2020
a09987a
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 22, 2020
65859a0
IGNITE-13856 linear performance for DirectByteBufferStreamImplV2.writ…
aries-3 Dec 28, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -301,6 +302,9 @@ public class DirectByteBufferStreamImplV2 implements DirectByteBufferStream {
/** */
protected boolean lastFinished;

/** map for cashing byte-array representations of strings */
private Map<String, byte[]> stringsMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you using a map here? A simple byte array is enough, isn't it?


/**
* @param msgFactory Message factory.
*/
Expand Down Expand Up @@ -584,7 +588,29 @@ public DirectByteBufferStreamImplV2(MessageFactory msgFactory) {

/** {@inheritDoc} */
@Override public void writeString(String val) {
writeByteArray(val != null ? val.getBytes() : null);
if (val != null) {
if (buf.capacity() < val.length()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this condition is right. for example if 'buf.capacity() > val.length()' and 'buf.remaining() < val.length()' that it still requires to cache the bytes but in your case this won't happen. So maybe it is better to remove that condition at all, I don't think that writing to the local variable is too expensive so you can do it every time even it isn't required for certain case. Or you should change you condition to the proper one.

if (stringsMap == null)
stringsMap = new HashMap<>();

byte[] bytes = stringsMap.computeIfAbsent(val, s -> s.getBytes());

try {
writeByteArray(bytes);
}
catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe if an exception appears here, this whole object will be invalid, for example, arrOff would be incorrect, so perhaps it's not necessary to handle this exception here.

stringsMap.remove(val);
throw e;
}

if (lastFinished)
stringsMap.remove(val);
}
else
writeByteArray(val.getBytes());
}
else
writeByteArray(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we perhaps declare byteArr a local variable, and only assign it to curStrBackingArr if not lastFinished? This way we will not touch this variable at all when string fits one frame.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we need to reset it to null if lastFinished. Need to figure out the logic, maybe it's too cumbersome and confusing to implement.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disregard this, we are going to read curStrBackingArr value either way. I think we may skip this change entirely, just rename var / mark volatile.

}

/** {@inheritDoc} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.StringUtils;
import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
import org.apache.ignite.internal.util.GridUnsafe;
Expand Down Expand Up @@ -339,6 +340,46 @@ public void testDoubleArrayInternal() {
testWriteArrayInternalOverflow(arr, true, true, 3);
}

/**
* tests linear performance for writeString method
* */
@Test
public void testLinearPerformanceForWriteString() {
int len = 40_000;

long t1 = getWriteStringExecutionTime(len);
long t2 = getWriteStringExecutionTime(len * 10);
long t3 = getWriteStringExecutionTime(len * 100);
long t4 = getWriteStringExecutionTime(len * 1000);

assertTrue(t2 <= t1 * 10);
assertTrue(t3 <= t1 * 100);
assertTrue(t4 <= t1 * 1000);
}

/**
* execution time
* @param len string length
* @return writing time
* */
private long getWriteStringExecutionTime(int len) {
String s = StringUtils.leftPad("1", len, "_");

buff.rewind();

DirectByteBufferStreamImplV2 stream = createStream(buff);

long d1 = System.currentTimeMillis();
while (!stream.lastFinished()) {
stream.writeString(s);

buff.rewind();
}
long d2 = System.currentTimeMillis();

return d2 - d1;
}

/**
* @param srcArr Source array.
* @param writeBigEndian If {@code true}, then write in big-endian mode.
Expand Down