ตัวอย่างการแก้ไขโค๊ดให้ดูง่ายขึ้นและทำงานเร็วขึ้น


การเขียนโปรแกรม

ตัวอย่างที่ 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 ครั้ง

  

 

 

คำสำคัญ (Tags): #เขียนโปรแกรม
หมายเลขบันทึก: 80549เขียนเมื่อ 25 กุมภาพันธ์ 2007 15:36 น. ()แก้ไขเมื่อ 7 เมษายน 2012 01:09 น. ()สัญญาอนุญาต: จำนวนที่อ่านจำนวนที่อ่าน:


ความเห็น (5)

สวัสดีครับ

      เห็นด้วยอย่างยิ่งครับ การลดกระบวนการที่นำเสนอมานี้ ล้วนจะมีผลต่อการคำนวณทั้งสิ้นครับ โดยเฉพาะการคำนวณกับข้อมูลที่เยอะแล้ววนทำซ้ำหลายรอบจะมีการสูญเสียเวลา ดังนั้นหลักสูตรการเรียนรู้ในเรื่องการเขียนโปรแกรมมีความจำเป็นที่จะต้องให้ความรู้เรื่องเซทและลอจิก กับนักเรียนตลอดจนการลดทอนเทอมหรือลอจิกให้อยู่ในรูปอย่างง่ายก่อนการเขียนโปรแกรม เหมือนที่มีคำตลกขำขันว่า หากโปรแกรมเมอร์เขียนโปรแกรมอย่างไม่มีลอจิกที่ดีพอ โปรแกรมที่ได้อาจจะเป็นโปรแกรมเบล่อแทนครับ อิๆ

ดีครับไว้ผมจะมาติดตามบ่อยๆครับ

 

บ่อยครั้งที่ผมต้องกลับมาแก้ให้โปรแกรมของตัวเอง แลสวยงามขึ้น
  • งง ว่าพลาดบันทึกนี้ไปได้อย่างไร
  • อยากมาชวนอาจารย์ไปบ้านครูบาครับผม
  • วันที่ 5-7เมษายนครับ

ขอบคุณมากครับ  อาจารย์เห็นได้ชัดเลยว่ามีประโยชน์ต่อนร.  นศ.  ในการเอาไปใช้ต่อมั่กๆ  :D

บางอันผมก็ไม่เคยคิดว่าจะทำได้มาก่อน 

พบปัญหาการใช้งานกรุณาแจ้ง LINE ID @gotoknow
ClassStart
ระบบจัดการการเรียนการสอนผ่านอินเทอร์เน็ต
ทั้งเว็บทั้งแอปใช้งานฟรี
ClassStart Books
โครงการหนังสือจากคลาสสตาร์ท