며칠전에 사석에서 상사분이 Tomcat은 IIS에 비해서 connection을 적게 받고, 그로 인해서 성능이 떨어진다고 말씀을 하시네요.. ^^;; 서비스의 전체적인 성능 문제가 Java 및 Tomcat에 기인을 하고 있다고 생각을 하는것 같아서.. 같은 개발자 입장에서 타 분야에 대한 경험으로 얘기하는게 아니라 말 그대로 선입견(Overlapped I/O의 성능만 말씀하시네 ^^;;)으로 얘기를 하는 듯한 느낌이었습니다.
서비스의 성능저하는 Tomcat이나 IIS보다는 그 위에 올라가는 어플이 더 성능에 영향을 미칠텐데 말입니다. ^^;;
그래서 IIS 기반의 ASP.NET 서비스들이 주로 사용하는 DataSet에 대해서 Serialize 데이타에 대해서 살펴보았습니다. 비교는 단순하게 Java , C# Object, C# DataSet으로 10개의 리스트를 가지는 모델을 가지고 하였습니다.
아래의 코드로 Java에서의 Object Array, C#에서의 Object Array, C#에서의 DataSet의 Serialize된 객체의 사이즈를 알수 있겠습니다. 단순하게 Serialize하는 속도 및 Deserialize하는 속도는 같다고 가정을 합니다.
* Java
SerializeModel.java
import java.util.ArrayList;
import java.io.Serializable;public class SerializeModel implements Serializable {
private static final long serialVersionUID = -7168303693593724718L;
private int count = 0;
private String name = null;
private String address = null;
private ArrayList<SerializeModel> models = new ArrayList<SerializeModel>();
public SerializeModel(int count, String name, String address) {
this.count = count;
this.name = name;
this.address = address;
}public void addModel(SerializeModel model) {
this.models.add(model);
}
}
SerializeTest.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;public class SerializeTest {
public static void main(String[] args) throws Exception {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("java.ser"));
SerializeModel model = new SerializeModel(0, "a", "b");
for(int i=0; i<10; i++) {
model.addModel(new SerializeModel(i, i +" name", i +" address"));
}
out.writeObject(model);
out.flush();
out.close();
}
}
* C#
SerializeModel.cs
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;namespace SerialzieTest
{
[Serializable()]
class SerializeModel
{
private int count = 0;
private String name = null;
private String address = null;
private ArrayList models = new ArrayList();
public SerializeModel(int count, String name, String address) {
this.count = count;
this.name = name;
this.address = address;
}public void AddModel(SerializeModel model) {
this.models.Add(model);
}
}
}
SerializeModelDataSet.cs
using System;
using System.Data;
using System.Collections.Generic;
using System.Text;namespace SerialzieTest
{
[Serializable]
class SerializeModelDataSet
{
private DataSet dataSet = new DataSet();
public void AddDataTable(DataTable table) {
this.dataSet.Tables.Add(table);
}public DataSet GetDataSet()
{
return this.dataSet;
}
}
}
Program.cs
using System;
using System.Data;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;namespace SerialzieTest
{
class Program
{
static void SerializeObjectArray()
{
Stream stream = File.Open("csharp.ser", FileMode.Create);
BinaryFormatter bformat = new BinaryFormatter();SerializeModel model = new SerializeModel(0, "a", "b");
for (int i = 0; i < 10; i++)
{
model.AddModel(new SerializeModel(i, i + " name", i + " address"));
}
bformat.Serialize(stream, model);
stream.Flush();
stream.Close();
}static void SerializeDataSet()
{
Stream stream = File.Open("csharp_dataset.ser", FileMode.Create);
BinaryFormatter bformat = new BinaryFormatter();
SerializeModelDataSet model = new SerializeModelDataSet();DataTable table = new DataTable();
DataColumn itemCount = new DataColumn("count", Type.GetType("System.Int32"));
DataColumn itemName = new DataColumn("name", Type.GetType("System.String"));
DataColumn itemAddress = new DataColumn("address", Type.GetType("System.String"));table.Columns.Add(itemCount);
table.Columns.Add(itemName);
table.Columns.Add(itemAddress);DataRow row;
for (int i = 0; i < 10; i++)
{
row = table.NewRow();
row["count"] = i;
row["name"] = i + " name";
row["address"] = i + " address";
table.Rows.Add(row);
}
model.AddDataTable(table);
bformat.Serialize(stream, model);
stream.Flush();
stream.Close();
}static void Main(string[] args)
{
SerializeObjectArray();
SerializeDataSet();
}
}
}
위의 코드를 통해서 저장한 Object의 사이즈는 아래와 같습니다.
C#(Object ArrayList) : 1035 byte
C#(DataSet) : 3000 byte
네트웍을 통해서 전송되는 Data의 크기는 성능에 중요한 영향을 미치지요..
실제로 성능을 높이기 위해서 Socket Buffer의 사이즈를 적당히 줄이는 것도 팁으로 나와 있구요..
위 상황에서 C#의 DataSet은 더욱 멋진 모습을 보여줍니다.
아래의 화면처럼 말이죠.. 아래의 화면은 Hex Viewer로 본 화면입니다.
Object의 Serialize는 C#이 version, locale 및 가비지(?) 데이타로 인해서 좀 더 크게 나옵니다.
그리고, 중간의 DataSet은 Serialize된 내용에 xml의 형태로 저장을 하고 있네요.. 결국 DataSet이 데이타로 네트웍을 통해서 전송이 되면, 사이즈보다는 Serialize/Deserialize할때의 String연산(XML 데이타 리드)이 성능저하의 주범이 되지 않을까요? 결국, Tomcat, IIS가 중요한게 아니라 C#에서 널리 쓰이는 DataSet을 많이 사용하고 있는 IIS기반의 ASP.NET 어플들의 서비스가 더 성능이 안 좋을 거라는 생각이 드네요... ^^;;;;
'Java' 카테고리의 다른 글
| 자바 메모리 구조 (0) | 2010/01/27 |
|---|---|
| convert nanoseconds to seconds or milliseconds (0) | 2010/01/27 |
| Java vs C# Serialize 비교 또는 C# DataSet을 쓰지 말아야 되는 이유(?) (4) | 2010/01/15 |
| Exception StackTrace to a String (0) | 2009/11/24 |
| addShutdownHook() problem with java.util.Timer instance (0) | 2009/11/24 |