Skip to content

Instantly share code, notes, and snippets.

@jackeylu
Created July 18, 2016 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackeylu/32f9fa35abb84faf42fb25993ec70874 to your computer and use it in GitHub Desktop.
Save jackeylu/32f9fa35abb84faf42fb25993ec70874 to your computer and use it in GitHub Desktop.
benchmark on serialization, Ignite Binary Marshaller vs. Protostuff
package example.perf.protostuff;
/**
* Created by jackeylv on 2016/7/13.
*/
public class Foo {
private Object object;
public Foo(){
object = null;
}
public Foo(Object object){
this.object = object;
}
public Object getObject(){
return object;
}
public void setObject(Object object){
this.object = object;
}
}
package data.media;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Created by jackeylv on 2016/7/18.
*/
public class GenMediaContent {
public static MediaContent build(int type){
assert type==1 || type == 2 : "type should only be 1 or 2.";
Media media = new Media();
List<Image> images = new LinkedList<>();
switch (type){
case 1:
media.setUri("http://javaone.com/keynote.mpg");
media.setTitle("Javaone Keynote");
media.setWidth(640);
media.setHeight(480);
media.setFormat("video/mpg4");
media.setDuration(18000000); // half hour in milliseconds
media.setSize(58982400); // bitrate * duration in seconds / 8 bits per byte
media.setPersons(Arrays.asList("Bill Gates", "Steve Jobs"));
media.setPlayer(Media.Player.JAVA);
media.setCopyright(null);
images.add(new Image("http://javaone.com/keynote_large.jpg",
"Javaone Keynote",
1024,
768,
Image.Size.LARGE
));
images.add(new Image("http://javaone.com/keynote_small.jpg",
"Javaone Keynote",
320,
240,
Image.Size.SMALL
));
break;
case 2:
media.setUri("http://javaone.com/keynote.ogg");
media.setTitle(null);
media.setWidth(641);
media.setHeight(481);
media.setFormat("video/theora");
media.setDuration(18000001);
media.setSize(58982401);
media.setPersons(Arrays.asList("Bill Gates, Jr.", "Steven Jobs"));
media.setPlayer(Media.Player.FLASH);
media.setCopyright("2009, Scooby Doo");
images.add(new Image("http://javaone.com/keynote_huge.jpg",
"Javaone Keynote",
32000,
24000,
Image.Size.LARGE
));
images.add(new Image("http://javaone.com/keynote_large.jpg",
null,
1024,
768,
Image.Size.LARGE
));
images.add(new Image("http://javaone.com/keynote_small.jpg",
null,
320,
240,
Image.Size.SMALL
));
break;
default:
throw new AssertionError("type should only be 1 or 2");
}
return new MediaContent(media, images);
}
}
package example.perf.ignite;
import example.datahelper.DataHelper;
import example.datahelper.ObjectEquals;
import example.perf.util.*;
import org.apache.commons.io.HexDump;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.Ignition;
import org.apache.ignite.binary.BinaryBasicIdMapper;
import org.apache.ignite.binary.BinaryBasicNameMapper;
import org.apache.ignite.configuration.BinaryConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.binary.BinaryMarshaller;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
/**
* Created by jackeylv on 2016/6/23.
*/
public class IgniteMarshaller {
public static void main(String[] args) throws IgniteCheckedException, IllegalAccessException, IOException {
System.out.println(OptionsHelper.getMainClassAndArgs());
MarshallerParameters cfg = new MarshallerParameters();
OptionsHelper.jcommander(args, cfg, "");
if (cfg.help){
System.err.println(OptionsHelper.usage(null));
return;
}
System.out.println(cfg);
System.out.println("Statics result will be store into file "
+ System.getProperty("user.dir") + File.separator + cfg.output_file);
withIgniteInstance(cfg);
}
public static void withIgniteInstance(MarshallerParameters cfg) throws IllegalAccessException, IOException, IgniteCheckedException {
IgniteConfiguration icfg = new IgniteConfiguration();
icfg.setIgniteHome(System.getProperty("user.dir"));
icfg.setWorkDirectory(System.getProperty("user.dir"));
BinaryConfiguration bCfg = new BinaryConfiguration();
bCfg.setCompactFooter(true);
bCfg.setNameMapper(new BinaryBasicNameMapper(false));
bCfg.setIdMapper(new BinaryBasicIdMapper(false));
icfg.setMarshaller(new BinaryMarshaller());
icfg.setBinaryConfiguration(bCfg);
try (Ignite ignite = Ignition.start(icfg)) {
BinaryMarshaller marshaller = (BinaryMarshaller) icfg.getMarshaller();
PrintStream output = cfg.output();
output.println("Case,InputSize(bytes),AvgConvertingSpeed," +
"AvgConvertingSpeed(bps),time_cost(ms),AvgCompressedSize(bytes)");
for (DataHelper.DataType v : DataHelper.DataType.values()){
int num_obj = cfg.num;
if (v.equals(DataHelper.DataType.STRING_ARRAY))
num_obj = 100;
System.out.println("Processing Data type " + v.name());
ArrayList<Object> objectArrayList = DataHelper.buildData(num_obj, v);
long bytes = DataHelper.CalculateSize(objectArrayList);
Summary input_summary = new Summary(bytes, num_obj);
ArrayList<Long> compressed_size = new ArrayList<>(num_obj);
TimeRecord tr = new TimeRecord();
tr.reset();
for (int i = 0; i < num_obj; i++) {
Samsara(marshaller, objectArrayList.get(i), compressed_size, cfg.unmarshall, cfg.dump&&i==0);
}
long time_cost = tr.end();
Summary summary_compressed = Statics.summary(compressed_size);
output.println(v.name() + "," + input_summary.avg()
+"," + Format.speed(bytes, time_cost)
+ "," + (time_cost >0 ? 1000*bytes/time_cost : Long.MAX_VALUE ) +"," + time_cost
+ "," + summary_compressed.avg()
);
objectArrayList.clear();
}
}
}
//
// public static void noIgniteInstance() throws IgniteCheckedException, IllegalAccessException {
// BinaryMarshaller binaryMarshaller = binaryMarshaller();
//
// for (ArrayList<Object> lst : objectArrayLists) {
// int n = lst.size();
// long bytes = DataHelper.CalculateSize(lst);
// Summary input_summary = new Summary(bytes, n);
// ArrayList<Long> compressed_size = new ArrayList<>(n);
// TimeRecord tr = new TimeRecord();
// tr.reset();
// for (int i = 0; i < n; i++) {
// Samsara(binaryMarshaller,lst.get(i), compressed_size, false);
// }
// long time_cost = tr.end();
// Summary summary_compressed = Statics.summary(compressed_size);
//
// //long bytes = (long) (summary.avg()*n);
// //System.out.println("BinaryMarshaller.marshall perf " + Format.speed(bytes, time_cost));
// System.out.println("Avg Input size: " + input_summary.avg()
// + " bytes, converting speed " + Format.speed(bytes, time_cost)
// + ", avg compressed size = " + summary_compressed.avg()
// + " bytes."
// );
// }
// }
// public static BinaryMarshaller binaryMarshaller() throws IgniteCheckedException {
// String dir = System.getProperty("java.io.tmpdir");
// System.out.println("IgniteMarshaller.binaryMarshaller dir " + dir);
// IgniteUtils.setWorkDirectory(dir, null);
// IgniteConfiguration iCfg = new IgniteConfiguration();
// BinaryConfiguration bCfg = new BinaryConfiguration();
// iCfg.setBinaryConfiguration(bCfg);
// BinaryContext ctx = new BinaryContext(BinaryCachingMetadataHandler.create(), iCfg, new NullLogger());
// BinaryMarshaller marsh = new BinaryMarshaller();
// marsh.setContext(new MarshallerContextImpl(null));
// IgniteUtils.invoke(BinaryMarshaller.class, marsh, "setBinaryContext", ctx, iCfg);
//
// return marsh;
// }
public static void Samsara(BinaryMarshaller binaryMarshaller,
Object object,
ArrayList<Long> compressed_size,
boolean unmarshall,
boolean debug) throws IOException, IgniteCheckedException {
byte[] bytes = binaryMarshaller.marshal(object);
if (debug && bytes.length>0) {
HexDump.dump(bytes, 0, System.err, 0);
System.err.println("bytes: " + bytes.length);
}
compressed_size.add((long) bytes.length);
if (unmarshall){
Object back = binaryMarshaller.unmarshal(bytes, null);
ObjectEquals.assertEquals(object, back);
System.out.println(object);
System.out.println(back);
}
}
}
package data.media;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import static data.ReprUtil.repr;
@XmlAccessorType(XmlAccessType.FIELD)
public class Image implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
public enum Size {
SMALL, LARGE
}
public String uri;
public String title; // Can be null
public int width;
public int height;
public Size size;
public Image() {}
public Image (String uri, String title, int width, int height, Size size) {
this.height = height;
this.title = title;
this.uri = uri;
this.width = width;
this.size = size;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Image image = (Image) o;
if (height != image.height) return false;
if (width != image.width) return false;
if (size != image.size) return false;
if (title != null ? !title.equals(image.title) : image.title != null) return false;
if (uri != null ? !uri.equals(image.uri) : image.uri != null) return false;
return true;
}
@Override
public int hashCode()
{
int result = uri != null ? uri.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + width;
result = 31 * result + height;
result = 31 * result + (size != null ? size.hashCode() : 0);
return result;
}
public String toString () {
StringBuilder sb = new StringBuilder();
sb.append("[Image ");
sb.append("uri=").append(repr(uri));
sb.append(", title=").append(repr(title));
sb.append(", width=").append(width);
sb.append(", height=").append(height);
sb.append(", size=").append(size);
sb.append("]");
return sb.toString();
}
public void setUri(String uri) {
this.uri = uri;
}
public void setTitle(String title) {
this.title = title;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void setSize(Size size) {
this.size = size;
}
public String getUri() {
return uri;
}
public String getTitle() {
return title;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Size getSize() {
return size;
}
}
package data.media;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
import static data.ReprUtil.repr;
@SuppressWarnings("serial")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JaxbMedia")
public class Media implements java.io.Serializable {
public enum Player {
JAVA, FLASH;
public static Player find(String str) {
if (str == "JAVA") return JAVA;
if (str == "FLASH") return FLASH;
if ("JAVA".equals(str)) return JAVA;
if ("FLASH".equals(str)) return FLASH;
String desc = (str == null) ? "NULL" : String.format("'%s'", str);
throw new IllegalArgumentException("No Player value of "+desc);
}
}
public String uri;
public String title; // Can be unset.
public int width;
public int height;
public String format;
public long duration;
public long size;
public int bitrate; // Can be unset.
public boolean hasBitrate;
public List<String> persons;
public Player player;
public String copyright; // Can be unset.
public Media() {}
public Media(String uri, String title, int width, int height, String format, long duration, long size, int bitrate, boolean hasBitrate, List<String> persons, Player player, String copyright)
{
this.uri = uri;
this.title = title;
this.width = width;
this.height = height;
this.format = format;
this.duration = duration;
this.size = size;
this.bitrate = bitrate;
this.hasBitrate = hasBitrate;
this.persons = persons;
this.player = player;
this.copyright = copyright;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Media media = (Media) o;
if (bitrate != media.bitrate) return false;
if (duration != media.duration) return false;
if (hasBitrate != media.hasBitrate) return false;
if (height != media.height) return false;
if (size != media.size) return false;
if (width != media.width) return false;
if (copyright != null ? !copyright.equals(media.copyright) : media.copyright != null) return false;
if (format != null ? !format.equals(media.format) : media.format != null) return false;
if (persons != null ? !persons.equals(media.persons) : media.persons != null) return false;
if (player != media.player) return false;
if (title != null ? !title.equals(media.title) : media.title != null) return false;
if (uri != null ? !uri.equals(media.uri) : media.uri != null) return false;
return true;
}
@Override
public int hashCode()
{
int result = uri != null ? uri.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + width;
result = 31 * result + height;
result = 31 * result + (format != null ? format.hashCode() : 0);
result = 31 * result + (int) (duration ^ (duration >>> 32));
result = 31 * result + (int) (size ^ (size >>> 32));
result = 31 * result + bitrate;
result = 31 * result + (hasBitrate ? 1 : 0);
result = 31 * result + (persons != null ? persons.hashCode() : 0);
result = 31 * result + (player != null ? player.hashCode() : 0);
result = 31 * result + (copyright != null ? copyright.hashCode() : 0);
return result;
}
public String toString () {
StringBuilder sb = new StringBuilder();
sb.append("[Media ");
sb.append("uri=").append(repr(uri));
sb.append(", title=").append(repr(title));
sb.append(", width=").append(width);
sb.append(", height=").append(height);
sb.append(", format=").append(repr(format));
sb.append(", duration=").append(duration);
sb.append(", size=").append(size);
sb.append(", hasBitrate=").append(hasBitrate);
sb.append(", bitrate=").append(String.valueOf(bitrate));
sb.append(", persons=").append(repr(persons));
sb.append(", player=").append(player);
sb.append(", copyright=").append(repr(copyright));
sb.append("]");
return sb.toString();
}
public void setUri(String uri) {
this.uri = uri;
}
public void setTitle(String title) {
this.title = title;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void setFormat(String format) {
this.format = format;
}
public void setDuration(long duration) {
this.duration = duration;
}
public void setSize(long size) {
this.size = size;
}
public void setBitrate(int bitrate) {
this.bitrate = bitrate;
this.hasBitrate = true;
}
public void setPersons(List<String> persons) {
this.persons = persons;
}
public void setPlayer(Player player) {
this.player = player;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
public String getUri() {
return uri;
}
public String getTitle() {
return title;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public String getFormat() {
return format;
}
public long getDuration() {
return duration;
}
public long getSize() {
return size;
}
public int getBitrate() {
return bitrate;
}
public List<String> getPersons() {
return persons;
}
public Player getPlayer() {
return player;
}
public String getCopyright() {
return copyright;
}
}
package data.media;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@SuppressWarnings("serial")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MediaContent implements java.io.Serializable
{
public Media media;
public List<Image> images;
public MediaContent() {}
public MediaContent (Media media, List<Image> images) {
this.media = media;
this.images = images;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MediaContent that = (MediaContent) o;
if (images != null ? !images.equals(that.images) : that.images != null) return false;
if (media != null ? !media.equals(that.media) : that.media != null) return false;
return true;
}
@Override
public int hashCode()
{
int result = media != null ? media.hashCode() : 0;
result = 31 * result + (images != null ? images.hashCode() : 0);
return result;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[MediaContent: ");
sb.append("media=").append(media);
sb.append(", images=").append(images);
sb.append("]");
return sb.toString();
}
public void setMedia(Media media) {
this.media = media;
}
public void setImages(List<Image> images) {
this.images = images;
}
public Media getMedia() {
return media;
}
public List<Image> getImages() {
return images;
}
}
package example.perf.protostuff;
import example.datahelper.DataHelper;
import example.datahelper.ObjectEquals;
import example.perf.util.*;
import io.protostuff.*;
import io.protostuff.runtime.DefaultIdStrategy;
import io.protostuff.runtime.Delegate;
import io.protostuff.runtime.IdStrategy;
import io.protostuff.runtime.RuntimeSchema;
import org.apache.commons.io.HexDump;
import java.io.*;
import java.sql.Date;
import java.util.ArrayList;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
public class ProtoStuffMarshaller {
public static void main(String[] args) throws IOException, IllegalAccessException {
MarshallerParameters cfg = new MarshallerParameters();
OptionsHelper.jcommander(args, cfg, "");
if (cfg.help){
System.err.println(OptionsHelper.usage(null));
return;
}
System.out.println(cfg);
System.out.println("Statics result will be store into file "
+ System.getProperty("user.dir") + File.separator + cfg.output_file);
DefaultIdStrategy idStrategy = new DefaultIdStrategy();
idStrategy.registerDelegate(DATE_DELEGATE);
RunWithProtoStuff(cfg, idStrategy);
}
private static void RunWithProtoStuff(MarshallerParameters cfg, IdStrategy idStrategy) throws IllegalAccessException, IOException {
PrintStream output = cfg.output();
output.println("Case,InputSize(bytes),AvgConvertingSpeed," +
"AvgConvertingSpeed(bps),time_cost(ms),AvgCompressedSize(bytes)");
for (DataHelper.DataType v : DataHelper.DataType.values()){
int n = cfg.num;
if (v.equals(DataHelper.DataType.STRING_ARRAY))
n = 100;
System.out.println("Prepare data type " + v.name());
// if (v.equals(DataHelper.DataType.CONTACT)
// || v.equals(DataHelper.DataType.FIXED_CONTACT)){
// System.out.println("Ignored " + v);
// continue;
// }
ArrayList<Object> lst = DataHelper.buildData(n, v);
long bytes = DataHelper.CalculateSize(lst);
Summary input_summary = new Summary(bytes, n);
ArrayList<Long> compressed_size = new ArrayList<>(n);
TimeRecord tr = new TimeRecord();
tr.reset();
marshal(lst, compressed_size, cfg.unmarshall, cfg.dump, idStrategy);
long time_cost = tr.end();
Summary summary_compressed = Statics.summary(compressed_size);
output.println(v.name() + "," + input_summary.avg()
+"," + Format.speed(bytes, time_cost)
+ "," + (time_cost >0 ? 1000*bytes/time_cost : Long.MAX_VALUE ) +"," + time_cost
+ "," + summary_compressed.avg()
);
}
}
private static void marshal(ArrayList<Object> objectArrayList,
ArrayList<Long> compressed_size,
boolean unmarshall, boolean dump, IdStrategy idStrategy) throws IOException {
int num = 0;
for (Object o: objectArrayList) {
Foo foo = new Foo(o);
Schema schema = RuntimeSchema.getSchema(Foo.class, idStrategy);
LinkedBuffer buffer = LinkedBuffer.allocate();
byte[] bytes = ProtostuffIOUtil.toByteArray(foo, schema, buffer);
//byte[] compressed = compressDeflate(bytes);
//bytes = compressed;
buffer.clear();
compressed_size.add((long) bytes.length);
if (dump && num == 0 && bytes.length>0) {
HexDump.dump(bytes, 0, System.err, 0);
System.err.println("Bytes: " + bytes.length);
}
num++;
if (unmarshall){
//byte[] deCompressed = deCompressDeflate(bytes);
//bytes = deCompressed;
Object ignore = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, ignore, schema);
ObjectEquals.assertEquals(foo.getObject(), ((Foo) ignore).getObject());
System.out.println(foo.getObject());
System.out.println(((Foo) ignore).getObject());
}
}
}
public static final Delegate<java.sql.Date> DATE_DELEGATE = new Delegate<Date>() {
@Override
public WireFormat.FieldType getFieldType() {
return WireFormat.FieldType.FIXED64;
}
@Override
public Date readFrom(Input input) throws IOException {
return new Date(input.readFixed64());
}
@Override
public void writeTo(Output output, int number, Date value, boolean repeated) throws IOException {
output.writeFixed64(number, value.getTime(), repeated);
}
@Override
public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
output.writeFixed64(number, input.readFixed64(), repeated);
}
@Override
public Class<?> typeClass() {
return java.sql.Date.class;
}
};
protected static byte[] compressDeflate(byte[] data)
{
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream(500);
DeflaterOutputStream compresser = new DeflaterOutputStream(bout);
compresser.write(data, 0, data.length);
compresser.finish();
compresser.flush();
return bout.toByteArray();
}
catch (IOException ex) {
AssertionError ae = new AssertionError("IOException while writing to ByteArrayOutputStream!");
ae.initCause(ex);
throw ae;
}
}
private static byte[] deCompressDeflate(byte[] in) {
ByteArrayInputStream stream = new ByteArrayInputStream(in);
InflaterInputStream zip = new InflaterInputStream(stream);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte b[] = new byte[4092];
try {
int n;
while ((n = zip.read(b)) >= 0) {
out.write(b, 0, n);
}
zip.close();
out.close();
return out.toByteArray();
}
catch (Exception e) {
AssertionError ae = new AssertionError("IOException while writing to ByteArrayInputStream!");
ae.initCause(e);
throw ae;
}
}
}
package data;
public class ReprUtil
{
public static String repr(String s)
{
if (s == null) return "null";
return '"' + s + '"';
}
public static String repr(Iterable<String> it)
{
StringBuilder buf = new StringBuilder();
buf.append('[');
String sep = "";
for (String s : it) {
buf.append(sep); sep = ", ";
buf.append(repr(s));
}
buf.append(']');
return buf.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment