ตัวอย่างที่ 1 โค๊ดที่้ต้องทำอยู่แล้วไม่ควรเอามาใส่ไว้ใน if () {...} else {...}
จากเดิม
if (SBuff.length() < 1024)
{
SBuff.append ("\n");
}
else
{
SBuff.append ("\n");
emit(SBuff+"",true);
}
ควรจะแก้เป็น
sBuff.append("\n");
if (SBuff.length() >= 1024) {
emit(SBuff+"",true);
}
ตัวอย่างที่ 2 ไม่ควรจะใช้ตัวเลขที่คนอื่นอ่านโปรแกรมแล้วอาจจะไม่เข้าใจ
จากเดิม
if (SBuff.length() >= 1024) {
emit(SBuff+"",true);
}
ควรจะแก้เป็น
final int MAX_CHARS = 1024;
if (SBuff.length() >= MAX_CHARS) {
emit(SBuff+"",true);
}
จากโปรแกรมเดิมที่มี 1024 ปรากฎอยู่ 19 ครั้ง หากแก้ต้องตามแก้ 19 ที่ แต่หากใช้วิธีที่แนะนำแก้แค่ที่การกำหนดค่าของตัวแปร MAX_CHARS ที่เดียว
ตัวอย่างที่ 3 ไม่ควรจะทำการคำนวณค่าคงที่ในแต่ละครั้งที่เข้ามาในลูป
จากเดิม
for(int i=1;i<=indentLevel-1;i++)
{
sEle2 = sT3.pop().toString();
sT1.push(sEle2);
}
ควรจะแก้เป็น
for(int i=1;i< indentLevel;i++) {
sEle2 = sT3.pop().toString();
sT1.push(sEle2);
}
จากเดิม
for(int i=0;i<attrs.getLength();i++){
....
}
ควรจะแก้เป็น
int numAttrs = attrs.getLength();
for(int i=0;i<numAttrs;i++){
....
}
ตัวอย่างที่ 4 ไม่ควรจะูใช้ if โดยไม่จำเป็น
จากเดิม
for(int i=1;i< indentLevel;i++) {
if(i==1){
SBuff.append("<x"+sT2.pop());
} else {
SBuff.append(""+sT2.pop());
}
if (SBuff.length() >= 1024)
emit(SBuff+"",true);
}
ควรจะแก้เป็น
SBuff.append("<x"+sT2.pop());
for(int i=2;i< indentLevel;i++) {
SBuff.append(""+sT2.pop());
if (SBuff.length() >= 1024)
emit(SBuff+"",true);
}
ตัวอย่างที่ 5 ควรจะใช้ Stringbuffer ในการเอาข้อความมาต่อกันมากกว่าจะใช้เครื่องหมาย + เพราะเมื่อใช้เครื่องหมาย + ระบบจะทำการสร้างข้อความทั้งหมดโดยการคัดลอกข้อความเก่าและข้อความใหม่ แต่ถ้าหากใช้ StringBuffer จะมีพื้นที่ที่เอาข้อความใหม่มาต่อจากข้อความเดิมเลย
จากเดิม
Buff = Buff + "<m f=" + "\"";
ควรจะแก้เป็น
Buff.append("<m f=\"");
ตัวอย่างที่ 6 ไม่ควรสร้างออปเจกต์ใหม่โดยไม่จำเป็นเพราะจะทำให้เปลืองพื้นที่ความจำและโปรแกรมรันช้า
จากเดิม
private void emit(String s,boolean append)
throws SAXException {
try{
StringWriter stringOut = new StringWriter();
File bFile = new File(a[0]+"_c.xml");
FileOutputStream fOut = new FileOutputStream(bFile,append);
fOut.write(s.getBytes());
fOut.close();
out.flush();
SBuff.delete(0,SBuff.length());
}catch(IOException e){
throw new SAXException("I/O error", e);
}
}
โดยที่ emit() ถูกเรียกใช้บ่อยมากถึง 13,339 ครั้ง เพราะฉะนั้นโปรแกรมเดิมจะเสียเวลามากกับการรันฟังก์ชันนี้ หากต้องการให้โปรแกรมนี้เร็วขึ้น ก็ต้องทำให้ฟังก์ชันนี้เร็วขึ้น
หากพิจารณาในฟังก์ชัน emit() จะพบว่า stringOut ไม่เคยถูกใช้ เพราะฉะนั้นควรจะเอาออก ส่วนการสร้างออปเจกต์สำหรับเขียนไฟล์นั้นควรทำแค่ครั้งเดียว และนอกฟังก์ชันนี้
ควรจะแก้เป็น
static FileOutputStream fOut;
static PrintWriter outStream;
...
try {
fOut = new FileOutputStream(bFile);
outStream = new PrintWriter(fOut);
} catch (IOException ioe) {
ioe.printStackTrace();
}
...
private void emit(String s) {
outStream.print(s);
outStream.flush();
SBuff.delete(0, SBuff.length());
}
ซึ่งทำให้โปรแกรมจากใช้เวลารัน 28.08 seconds มาเป็น 0.84 seconds เพราะว่าไม่ต้องเสียเวลาสร้างออปเจกต์ใหม่ 13,338*2 = 26, 676 ครั้ง
สวัสดีครับ
เห็นด้วยอย่างยิ่งครับ การลดกระบวนการที่นำเสนอมานี้ ล้วนจะมีผลต่อการคำนวณทั้งสิ้นครับ โดยเฉพาะการคำนวณกับข้อมูลที่เยอะแล้ววนทำซ้ำหลายรอบจะมีการสูญเสียเวลา ดังนั้นหลักสูตรการเรียนรู้ในเรื่องการเขียนโปรแกรมมีความจำเป็นที่จะต้องให้ความรู้เรื่องเซทและลอจิก กับนักเรียนตลอดจนการลดทอนเทอมหรือลอจิกให้อยู่ในรูปอย่างง่ายก่อนการเขียนโปรแกรม เหมือนที่มีคำตลกขำขันว่า หากโปรแกรมเมอร์เขียนโปรแกรมอย่างไม่มีลอจิกที่ดีพอ โปรแกรมที่ได้อาจจะเป็นโปรแกรมเบล่อแทนครับ อิๆ
ดีครับไว้ผมจะมาติดตามบ่อยๆครับ
ขอบคุณมากครับ อาจารย์เห็นได้ชัดเลยว่ามีประโยชน์ต่อนร. นศ. ในการเอาไปใช้ต่อมั่กๆ :D
บางอันผมก็ไม่เคยคิดว่าจะทำได้มาก่อน