ผมหายหัวไปเสียนาน ... เป็นเพราะมีเรื่องยุ่งๆ หลายอย่างเข้ามาในชีวิต (ตอนนี้ก็ยังยุ่งอยู่)ไม่ค่อยจะได้มีเวลาเข้ามาอ่าน หรือ เข้ามาโพสท์เลยจริงๆ แล้ว entry นี้ ผมเขียนไว้ตั้งแต่เมื่อปลายปีที่แล้ว (พฤศจิกายน 2547) แต่ว่า ไม่ได้เอามาตรวจทาน แล้วโพสท์ซักที ... วันนี้ถือว่าได้โอกาส เอามาตรวจทาน แล้วโพสท์ต่อให้จบเสียทีเชิญอ่านได้เลยครับต่อจากตอนที่แล้วนะครับจากปัญหาที่เกิดขึ้น ผมก็นึกถึงวิธีที่น่าจะแก้ปัญหาไว้ได้วิธีหนึ่ง ซึ่งขอเก็บไว้พูดสรุปในตอนจบดีกว่าเนื่องจากว่า ขณะที่แก้ปัญหา มีเวลาค่อนข้างน้อย ดังนั้นจึงไม่มีเวลาในการหาข้อมูลมากนัก ตอนนี้มาลองหาข้อมูลดูอีกครั้งหนึ่ง จนไปเจอเวปของ Xalan ซึ่งได้เขียน อธิบาย XPathAPI ไว้ดังนี้ซึ่งคาดไม่ถึงว่า คำว่า "a little slow" มันจะนานขนาดนี้ ...ซึ่งถ้าพูดถึงเวลาในการทำงานจริงๆ แล้วอาจจะไม่ถือว่านานเท่าไหร่ แต่ถ้าพิจารณาปริมาณ object ขยะที่สร้างขึ้นมา ต้องถือว่า ไม่สามารถรับได้ลองหาดูว่า มีวิธีอื่นที่เรา initialize object ต่างๆ เองหรือเปล่า ก็เจอการเขียนโดยใช้ API อีกแบบหนึ่ง ถ้าเทียบกับ output จากครั้งที่แล้ว จะเห็นว่าในครั้งนี้จะมีขั้นตอนในการ initialize เพิ่มขึ้นมา เนื่องจากว่า library ที่ใช้จะต้อง load grammar ที่ใช้ในการสร้าง data tree ขึ้นมา ซึ่งเห็นได้ว่าเสียเวลาไปหลายวินาที แต่เนื่องจากเวลาตรงนี้เป็น fixed cost ซึ่งจะเกิดขึ้นแค่ครั้งเดียวในการทำงานของโปรแกรม (ไม่ว่าจะอ่านข้อมูลกี่ไฟล์ก็ตาม) จึงน่าจะถือว่า cost ที่เพิ่มขึ้นมานี้ ไม่ significant เท่าไหร่จากผลจะเห็นว่า ใช้เวลาน้อยมากในการดึงข้อมูลตาม query string (ไม่ถึงวินาที) และไม่ได้เสีย memory ไปกับการทำงานมากเหมือนในครั้งก่อนเพื่อให้เห็นผลชัดเจน ก็ลองทดสอบอีกครั้งหนึ่งกับข้อมูลขนาดใหญ่ขึ้น เพื่อดูว่า ขนาดของข้อมูลมีผลกับความเร็วและการใช้ memory แค่ไหนจากผลจะเห็นว่า สำหรับข้อมูลขนาด 5,000 record โปรแกรมไม่ได้ใช้เวลาและ memory มากขึ้นอย่างมีนัยสำคัญเพื่อให้แน่ใจ ทดสอบอีกครั้งหนึ่งกับข้อมูล 10,000 recordก็จะเห็นว่า ได้ผลในลักษณะเดียวกัน จึงน่าจะพอได้ข้อสรุปคร่าวๆ ว่าการใช้ library ตัวนี้น่าจะช่วยแก้ปัญหานี้ได้แน่นอนว่าการตัดสินใจแบบนี้ เรียกได้ว่าเสี่ยงพอสมควร เพราะเป็นการรื้อแก้ในสิ่งที่ได้ทดสอบไปแล้ว ซ้ำยังเป็นการเปลี่ยนจากการใช้ library ที่ถือได้ว่ากึ่งๆ เป็นมาตรฐานและผ่านการทดสอบมาจากการใช้งานจริงมามากแล้ว เปลี่ยนมาเป็น library ที่เราทำขึ้นมาเอง ทดสอบกันเอง (ซึ่งต้องจัดว่า มีความน่าเชื่อถือน้อยกว่าอยู่มาก) แต่เนื่องจากผลที่คาดหวังทาง performance จึงจำเป็นที่จะต้องแก้ไขครั้งนี้หลังจากการแก้ไขเสร็จสิ้นลงแล้ว ก็ได้ทำการทดสอบกันอีกครั้งเพื่อดูว่า เราได้แก้ปัญหาไปได้จริงหรือไม่ ... ที่ข้อมูลขนาดไม่ใหญ่มาก ไม่เห็นข้อแตกต่างเท่าไหร่ ... แต่ที่ข้อมูลขนาดใหญ่ๆ โปรแกรมทำงานเร็วขึ้นถึงประมาณ 20 เท่าเลยทีเดียว!!! (จริงๆ จะพูดว่าทำงานเร็วขึ้นคงไม่ถูกนัก เพราะโปรแกรมก็ทำงานเท่าเดิม เหมือนเดิม .. ต้องพูดว่า GC ทำงานน้อยลงมากกว่า) ซึ่งจากผลที่ได้นี้ ต้องยอมรับว่าถือว่าอยู่ในระดับที่น่าพอใจ เพราะทำให้เวลาที่โปรแกรมใช้ในการทำงาน ลงมาอยู่ในระดับที่ยอมรับได้ในการใช้งานจริงใน production (ซึ่งก็ยังสามารถ tune ในจุดอื่นๆ ต่อไปได้อีก)ที่เขียนมานี่ไม่ได้บอกว่า XPath ไม่ดีแต่อย่างใด เพราะหากจะเปรียบเทียบ feature ของ XPath กับ library ที่สร้างขึ้นมาเองในกรณีนี้แล้ว ต้องยอมรับว่า XPath นั้นมีความสามารถในการทำ query มากกว่า library ที่สร้างขึ้นมานี้อยู่มาก แต่คงพอเป็นข้อควรระวังได้ (โดยเฉพาะสำหรับ Xalan implementation) สำหรับการใช้งานกับข้อมูลขนาดใหญ่มากๆ ซึ่งตรงนี้น่าจะเป็นประเด็นที่เกิดขึ้นกับ library ที่ทำงานกับ XML เกือบทุกตัวโดยส่วนตัวผมแล้ว คงจะสรุปว่ากรณี performance tuning นี้ ก็จบลงด้วยดี ถึงแม้ว่า effort ที่ใช้ในการแก้ไข และทดสอบ program จะถือว่าหนักหนาเอาการอยู่ แต่ก็สามารถปรับปรุงให้ performance ของโปรแกรมกลับมาอยู่ในระดับที่น่าพอใจได้ซึ่งกรณีนี้ ก็ได้ช่วยยืนยัน ความจำเป็นในการทำ profiling สำหรับการทำ tuning ได้อย่างชัดเจน เพราะถ้าไม่ได้ทำ profiling ก็ไม่มีทางหาสาเหตุที่แท้จริงของกรณีนี้ได้เลยถือว่า เล่าสู่กันฟังนะครับ
Quote
The methods in this class are convenience methods into the low-level XPath API. These functions tend to be a little slow, since a number of objects must be created for each evaluation. A faster way is to precompile the XPaths using the low-level API, and then just use the XPaths over and over.NOTE: In particular, each call to this method will create a new XPathContext, a new DTMManager... and thus a new DTM. That's very safe, since it guarantees that you're always processing against a fully up-to-date view of your document. But it's also potentially very expensive, since you're rebuilding the DTM every time. You should consider using an instance of CachedXPathAPI rather than these static methods.http://xml.apache.org/xalan-j/apidocs/org/...h/XPathAPI.html
import org.apache.xpath.domapi.XPathEvaluatorImpl;import org.w3c.dom.xpath.XPathEvaluator;import org.w3c.dom.xpath.XPathNSResolver;import org.w3c.dom.xpath.XPathResult;XPathEvaluator evaluator = new XPathEvaluatorImpl(doc);XPathNSResolver resolver = evaluator.createNSResolver(doc); // Evaluate the xpath expressionXPathResult callDetails = (XPathResult)evaluator.evaluate(xpath, doc, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE , null);ซึ่งจากการทดลองดู ก็ปรากฏว่ามีการใช้ memory ในปริมาณที่ใกล้เคียงกันกับ XPathAPIถึงตรงนี้ ผมคงไม่สรุปว่า การใช้ XPath กับ XML data ขนาดใหญ่ๆ จะมีปัญหาเรื่อง performance เสมอไปหรือไม่ แต่คงตั้งข้อสังเกตเกี่ยวกับการใช้ API ทั้งสองแบบนี้ไว้ว่า น่าจะต้องระวังเรื่องการทำงานกับ data ขนาดใหญ่ ในความเป็นจริงแล้วอาจจะมี API แบบอื่นที่สามารถทำงานได้มีประสิทธิภาพกว่านี้ คงจะจะต้องลองทดสอบกันก่อนที่จะใช้งานSolution อื่นที่เป็นไปได้นอกจากการใช้ XPath คือ การเขียน code เพื่อจะดึงข้อมูลออกมาจาก DOM โดยตรง ซึ่งค่อนข้างจะเป็นงานที่หนักหนาทีเดียว สำหรับข้อมูลจำนวนมาก ที่อยู่ลึกลงไปใน hierarchyสิ่งที่ต้องการ น่าจะเป็น วิธีการดึงข้อมูลโดยใช้ query string ในลักษณะที่คล้ายกับ XPath ... แต่มี memory footprint ที่น้อยกว่าย้อนกลับไปที่กระทู้ http://www.narisa.co...wtopic=7643&hl=ผมได้บ่นถึงการทำงานของ library ตัวหนึ่งที่ใช้ SAX Parser สร้าง object tree ขึ้นมาจาก XML data ซึ่งบังเอิญพอเหมาะพอดีกับสิ่งที่ต้องการในกรณีนี้พอดี ข้อมูลที่ใช้สำหรับโปรแกรมตัวนั้น กับโปรแกรมที่กำลังพูดถึงนี้ มีโครงสร้างที่เหมือนกัน (เป็นข้อมูลชนิดเดียวกัน) คือ เก็บข้อมูลใน Text element (ไม่ใช้ Attribute) เหมือนกัน .. มีโครงสร้างข้อมูล (ASCII text, integer, long, etc.) ที่ชัดเจนเหมือนกัน และประจวบเหมาะกับที่ library ตัวนี้ มี utility ที่ใช้สำหรับ query data node ตาม query string ได้อยู่แล้ว ... ดังนั้น library ตัวนี้จึงดูจะเป็นทางเลือกที่ดีที่จะเอามาใช้แทน DOM และ XPathแน่นอนว่า ปริมาณงานที่เกิดขึ้นในการแก้ code จากการอ่านข้อมูลจาก XPath มาเป็นการอ่านจาก library ตัวนี้ เยอะพอสมควร และจะต้องทดสอบกรณีต่างๆ ในการดึงข้อมูลใหม่ ดังนั้น การตัดสินใจที่จะ "โละ" ครั้งนี้ คงต้องมั่นใจในผลลัพธ์พอสมควรวิธีที่ดีที่สุด คงหนีไม่พ้นทดสอบเทียบกับกรณีของ XPath ที่ผมได้ทำไปในตอนที่แล้วเนื่องจากโปรแกรมที่เขียนขึ้นมาทดสอบมีลักษณะการทำงานเหมือนกับโปรแกรมทดสอบสำหรับ XPath และใช้ proprietary API (library ที่ทำขึ้นเอง) ผมคิดว่าคงไม่จำเป็นที่จะต้องดูโปรแกรมตัวนี้ เรามาดูผลกันเลยดีกว่า
Quote
Wed Nov 30 21:48:08 GMT+07:00 2005 : 265343848/265486336InitializingWed Nov 30 21:48:13 GMT+07:00 2005 : 246809176/265486336Wed Nov 30 21:48:13 GMT+07:00 2005 : 246713984/265486336Read contentWed Nov 30 21:48:15 GMT+07:00 2005 : 250957184/265486336Force GCWed Nov 30 21:48:15 GMT+07:00 2005 : 254419208/265486336Select call detail nodesWed Nov 30 21:48:15 GMT+07:00 2005 : 254376784/265486336Found 1000 itemsForce GCWed Nov 30 21:48:15 GMT+07:00 2005 : 254403336/265486336
Quote
Wed Nov 30 21:54:33 GMT+07:00 2005 : 265343848/265486336InitializingWed Nov 30 21:54:38 GMT+07:00 2005 : 246811640/265486336Wed Nov 30 21:54:38 GMT+07:00 2005 : 246716448/265486336Read contentWed Nov 30 21:54:44 GMT+07:00 2005 : 210390416/265486336Force GCWed Nov 30 21:54:45 GMT+07:00 2005 : 217523392/265486336Select call detail nodesWed Nov 30 21:54:45 GMT+07:00 2005 : 217431192/265486336Found 5000 itemsForce GCWed Nov 30 21:54:45 GMT+07:00 2005 : 217490936/265486336
Quote
Wed Nov 30 21:58:19 GMT+07:00 2005 : 265343840/265486336InitializingWed Nov 30 21:58:24 GMT+07:00 2005 : 246809272/265486336Wed Nov 30 21:58:24 GMT+07:00 2005 : 246714080/265486336Read contentWed Nov 30 21:58:34 GMT+07:00 2005 : 163949120/265486336Force GCWed Nov 30 21:58:35 GMT+07:00 2005 : 171761016/265551872Select call detail nodesWed Nov 30 21:58:35 GMT+07:00 2005 : 171591320/265551872Found 10000 itemsForce GCWed Nov 30 21:58:36 GMT+07:00 2005 : 171702736/265551872
0 Comments On This Entry
← September 2010 →
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Recent Entries
-
Burning up the Heap (Part II)on Aug 25 2006 02:35 PM
-
-
-
-
Help
Leave Comment








