- มีการยกเครื่องเครื่องมือภายในทั้งหมดเพื่อทำให้กระบวนการคอมไพล์ JavaScript·WebAssembly ของ เอนจิน SpiderMonkey มองเห็นได้ชัดเจนขึ้น พร้อมเพิ่มความสามารถในการสร้าง กราฟแบบโต้ตอบได้
- iongraph ที่อิง Graphviz เดิมมีปัญหาเรื่องเลย์เอาต์ไม่เสถียรและโครงสร้างไม่ชวนให้เข้าใจ ทำให้ประสิทธิภาพในการดีบักต่ำ จึงออกแบบ อัลกอริทึมเลย์เอาต์ใหม่ ขึ้นมาใช้แทนโดยตรง
- อัลกอริทึมใหม่นี้ทำให้ แนวทาง Sugiyama เรียบง่ายลงเพื่อแสดงโครงสร้างลูปได้ชัดเจน และสร้าง เลย์เอาต์ที่เสถียรและรวดเร็ว ด้วยโค้ด JavaScript ไม่ถึง 1000 บรรทัด
- กราฟใช้ เส้นเชื่อมตรงสไตล์แผนผังรถไฟ เพื่อให้อ่านง่ายขึ้น และทำความเร็วในการเรนเดอร์ได้มากกว่า Graphviz หลายพันเท่า
- เครื่องมือนี้ถูกรวมเข้ากับ Firefox Profiler แล้ว และมีแผนขยายต่อในอนาคต เช่น การค้นหาและการแสดงผลรีจิสเตอร์
การปรับปรุงเครื่องมือแสดงภาพของ SpiderMonkey
- มีการสร้างเครื่องมือใหม่เพื่อแสดงภาพกราฟภายในที่ คอมไพเลอร์เพิ่มประสิทธิภาพ Ion ของ SpiderMonkey สร้างขึ้น
- ผู้ใช้สามารถป้อนโค้ด JavaScript บนหน้าเว็บเพื่อ สำรวจกระบวนการเพิ่มประสิทธิภาพของฟังก์ชันเป็นกราฟแบบเรียลไทม์ ได้
- กราฟสามารถลาก ซูม และปรับด้วยสไลเดอร์เพื่อดูความเปลี่ยนแปลงในแต่ละขั้นได้
- iongraph ที่อิง Graphviz เดิมสร้างผลลัพธ์เป็น PDF แต่ ไม่สอดคล้องกับโครงสร้างของซอร์สโค้ด และมี ปัญหาความไม่เสถียรของผลลัพธ์ อย่างรุนแรง
- แม้แก้โค้ดเพียงเล็กน้อย ตำแหน่งของโหนดก็เปลี่ยนมาก ทำให้ เปรียบเทียบระหว่างแต่ละ pass ได้ยาก
- โครงสร้างของลูปและเงื่อนไขถูกบิดเบือนในเชิงภาพ ทำให้ เข้าใจ control flow ได้ยาก
ข้อจำกัดของ Graphviz และแนวทางใหม่
- อัลกอริทึม Sugiyama ของ Graphviz เหมาะกับการปรับกราฟทั่วไปให้เหมาะสม แต่ ไม่สะท้อนลักษณะเฉพาะของ control flow graph (CFG)
- ลูปของ JavaScript·WebAssembly มีจุดทางเข้าเพียงจุดเดียว และมี control flow แบบ reducible
- ทีม SpiderMonkey ใช้ข้อจำกัดเหล่านี้ในการออกแบบ อัลกอริทึมเฉพาะทางที่เรียบง่ายกว่า
- กำจัดวัฏจักร: มองข้าม back edge ของลูป
- จัดชั้น (Leveling): วางบล็อกหลังลูปให้ต่ำลงเพื่อสะท้อนลำดับการไหลของโค้ด
- ละการลดจุดตัดให้ต่ำสุด: ให้ความสำคัญกับความเสถียร โดยตรึงลำดับของแขนง true/false
- คงโครงสร้างแบบต้นไม้ของลูปไว้: ทำให้ลูปซ้อนกันแสดงผลได้ชัดเจนในเชิงภาพ
- ผลลัพธ์คือได้ เลย์เอาต์ที่กระชับ รวดเร็ว และเสถียร โดยการพัฒนาเริ่มต้นประกอบด้วย JavaScript ราว 1000 บรรทัด
ขั้นตอนของอัลกอริทึมเลย์เอาต์ iongraph
- ขั้นที่ 1: Layering
- จัดเรียงบล็อกตามชั้นและสะท้อนความสัมพันธ์ระหว่างภายในและภายนอกลูป
- บล็อกหลังจบลูปจะถูกวางต่ำลงตามความสูงทั้งหมดของลูป
- ขั้นที่ 2: สร้างโหนดจำลอง
- เพิ่มโหนดจำลองให้กับเส้นเชื่อมที่พาดข้ามหลายชั้นเพื่อ หลีกเลี่ยงการชนกันในเชิงภาพ
- รวมเส้นเชื่อมที่ไปยังปลายทางเดียวกันเพื่อลด สัญญาณรบกวนทางภาพ
- ขั้นที่ 3: จัดแนวเส้นเชื่อม (Straighten)
- จัดแนวโหนดพ่อแม่และลูกเพื่อ คงรูปแบบเส้นแนวตั้ง และใช้การเยื้องสำหรับลูป
- โหนดจำลองก็เข้าร่วมในกระบวนการจัดแนวด้วยเพื่อ ป้องกันการทับซ้อนและรักษาโครงสร้าง
- ขั้นที่ 4: ติดตามเส้นเชื่อมแนวนอน
- จัดเรียงเส้นเชื่อมแนวนอนเป็นหน่วย track เพื่อไม่ให้ทับกัน
- แยกขึ้นบนหรือลงล่างตามทิศทางของเส้น และรวมเส้นที่สามารถรวมกันได้เป็นเส้นเดียว
- ขั้นที่ 5: จัดวางแนวตั้ง (Verticalize)
- กำหนดพิกัด Y ให้แต่ละชั้นเพื่อ จัดวางความสูงอย่างสม่ำเสมอ และเพิ่มความอ่านง่าย
- ขั้นที่ 6: เรนเดอร์ (Render)
- ใช้เส้นเชื่อมตรง สไตล์แผนผังรถไฟ
- เส้นเชื่อมตัดกันได้เฉพาะในแนวตั้งและแนวนอน ทำให้ ทิศทางและโครงสร้างชัดเจน
ผลของอัลกอริทึมแบบเรียบง่าย
- แทนที่จะใช้การเพิ่มประสิทธิภาพที่ซับซ้อน ระบบเลือกใช้ การจัดวางตามกฎที่คาดเดาได้ เพื่อรักษา ความอ่านง่ายและความเสถียร
- การตรึงลำดับโหนดและทำให้เส้นเชื่อมเรียบง่ายลง ช่วย คงความสอดคล้องระหว่างแต่ละ pass
- การตัด constraint solver ออกไปทำให้ได้ โครงสร้างที่มนุษย์เข้าใจได้ง่าย
- สามารถออกแบบโดยยึดความหมายเป็นศูนย์กลางได้ เช่น การวางภายในลูปหรือการเลื่อนบล็อกถัดไปลงด้านล่าง
- ประสิทธิภาพดีขึ้น: กราฟของฟังก์ชัน zlib ที่ Graphviz ใช้เวลา 10 นาที สามารถเรนเดอร์ได้ใน 20 มิลลิวินาที
- ได้ทั้งความเร็วที่มากขึ้นหลายพันเท่าและการสำรวจที่สะดวกยิ่งขึ้น
แผนในอนาคต
- มีการรวม iongraph เข้ากับ Firefox Profiler เรียบร้อยแล้ว ทำให้ตรวจดูกราฟระหว่างการวิเคราะห์ประสิทธิภาพได้
- ขณะนี้ยังใช้ได้เฉพาะใน SpiderMonkey shell build และยังไม่รวมอยู่ใน browser build
- ฟีเจอร์ที่มีการเสนอไว้ในอนาคต
- ฟังก์ชันสำรวจขั้นสูง, การค้นหา, การแสดงผลการจัดสรรรีจิสเตอร์ เป็นต้น
- ยังไม่มีโรดแมปที่ชัดเจน และ ยินดีต้อนรับการมีส่วนร่วมแบบโอเพนซอร์ส
- สำหรับการทดลองในเครื่อง ให้ตั้งค่า
IONFLAGS=logs เพื่อสร้าง /tmp/ion.json แล้ว
สามารถโหลดได้จาก รุ่นเผยแพร่แบบแยกอิสระ
- ซอร์สโค้ดเผยแพร่อยู่บน GitHub และสามารถพูดคุยกับนักพัฒนาได้โดยตรงผ่าน ห้องแชต Matrix
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ถ้าจะเทียบให้แม่นยำ จริง ๆ แล้วไม่ใช่การเทียบกับ Graphviz ทั้งชุด แต่เป็นการเทียบกับ dot(1)
Graphviz คือเฟรมเวิร์กสำหรับการแสดงผลที่มี layout engine หลายตัวรวมอยู่ด้วย (dot, neato, fdp, sfdp, circo, twopi ฯลฯ)
ถ้าอัลกอริทึมที่เสนอใหม่นี้ถูกนำไปมีส่วนร่วมกับ Graphviz ได้ก็คงเจ๋งมาก
ดูเอกสารที่เกี่ยวข้องได้ที่ คำอธิบายภาษา Graphviz และ เอกสาร dot layout engine
มันอาจทำงานได้ดีกับ control flow graph (CFG) ที่มี reducible control flow แต่ก็น่าจะมีข้อยกเว้นซับซ้อนอีกเยอะ
แถม iongraph ยัง เขียนบน JavaScript ดังนั้นถ้าจะรวมเข้า Graphviz ก็ต้อง แปลงเป็น C ด้วยเครื่องมืออย่าง Claude
ความสามารถในการ ลงไปดู implementation ต้นฉบับของอัลกอริทึมด้วยตัวเอง นี่เหมือนเป็นซูเปอร์พาวเวอร์จริง ๆ
ในฐานะคนที่เคยทำงานแสดงผลซับซ้อนด้วย Graphviz ตอนแรกก็ตกใจที่มีคนลงมือ reimplement เอง
แต่พอเห็นโครงสร้างของอัลกอริทึมแล้วก็รู้สึกว่ามันอาจไม่ได้ซับซ้อนอย่างที่คิด
อย่างไรก็ตาม จนกว่าจะลงมือทำ implementation เสร็จจริง ๆ ก็ยังยากจะรู้ว่า ความซับซ้อนที่ซ่อนอยู่ มีอะไรบ้าง
ถ้า ปรับอัลกอริทึมทั่วไปให้เฉพาะกับโดเมนปัญหา ก็มักได้ผลลัพธ์ที่ดีกว่ามาก
แต่ส่วนใหญ่เราก็มักใช้วิธีสะดวกคือหยิบอัลกอริทึมอเนกประสงค์มาใช้ตรง ๆ
การออกแบบระบบให้เหมาะกับแอปพลิเคชันเฉพาะช่วยเพิ่มทั้ง ประสิทธิภาพ, การขยายระบบ, และความทนทานต่อความขัดข้อง ได้มาก
แต่ถ้าตั้งเป้าจะให้ดีขึ้นระดับ 1000 เท่า เวลา 1~2 ปีก็ผ่านไปไวมาก
ระบบจัด layout กราฟแบบทั่วไปต้องรองรับกรณีที่หลากหลายกว่ามาก จึงเลี่ยงไม่ได้ที่จะซับซ้อน
เพราะงั้นผมคิดว่าทางสายกลางที่ดีคือวิเคราะห์อินพุตก่อน แล้วใช้ fast path สำหรับเคสพิเศษ ส่วนที่เหลือใช้ อัลกอริทึมทั่วไปที่มีการรับประกัน
เป็นบทความที่ดีมาก อนึ่ง dot ของ Graphviz ไม่ได้เป็น implementation แบบบริสุทธิ์ของอัลกอริทึม Sugiyama
implementation จริงอธิบายไว้ละเอียดใน บทความบนเว็บไซต์
ถ้าดูภาพเปรียบเทียบ dot กับ iongraph บนกราฟขนาดใหญ่ จะเห็นว่า dot ปรับให้เหมาะกับ การลดพื้นที่รวม ขณะที่ iongraph ไม่ได้ทำแบบนั้น
การแสดงผลกราฟขนาดใหญ่ดูเท่มากก็จริง แต่ในทางปฏิบัติ ไม่ค่อยมีประโยชน์นัก
การทำ visualization ใช้ได้ผลแค่ระดับหลายสิบโหนด พอมากกว่านั้นก็เข้าใจยากเพราะ ความซับซ้อนของ edge
สุดท้ายมันจึงเวิร์กแค่กับตัวอย่างง่าย ๆ และในสภาพแวดล้อมซับซ้อนกลับยิ่งรบกวนมากกว่า
ปัญหาส่วนใหญ่มักย่อยลงเป็นหน่วยเล็กได้
แต่ Graphviz แม้กับกราฟเล็กก็ยัง ไม่ค่อยสวย ขณะที่ iongraph มี ความอ่านง่ายของเส้น ดีกว่ามาก
ระยะยาวผมคิดว่าจำเป็นต้องมีองค์ประกอบแบบอินเทอร์แอ็กทีฟ เช่น ค้นหา, เน้น/ซ่อน
สิ่งที่น่าอึดอัดคือข้อจำกัดที่ไดอะแกรม ส่งออกหรือรับลิงก์ไม่ได้
Mermaid เองก็ทำลิงก์ในข้อความได้ แต่ลิงก์ในไดอะแกรมยังจำกัด
ดู การอภิปรายที่เกี่ยวข้องบน StackOverflow ได้เช่นกัน
เราต้องการเครื่องมือที่ พิจารณาฟีเจอร์แบบนี้เป็นฟีเจอร์ระดับชั้นหนึ่งตั้งแต่ขั้นออกแบบ
จุดแข็งที่แท้จริงของ Graphviz คือ ภาษา dot
กราฟที่นิยามด้วย dot มี ความเข้ากันได้ข้ามเครื่องมือ สูงมาก และตัวไวยากรณ์ก็เรียบง่ายอ่านง่าย
แม้จะมีตัวเลือกอย่าง Mermaid เกิดขึ้นมา แต่ dot ก็น่าจะยังอยู่ยาวในฐานะ ฟอร์แมตมาตรฐาน
เป็นบทความที่เจ๋งมาก
เลยสงสัยว่าเทคนิคแบบนี้ถูกใช้ใน TALA layout engine ของ D2 ด้วยหรือเปล่า
ดูตัวอย่าง TALA
ถ้าสนใจ graph drawing ขอแนะนำ คอร์สของ Will Evans(ลิงก์)
ผมเคยส่ง bugfix ให้ Dot lexer ของ Open Graph Drawing Framework(OGDF) มาก่อน
โดย OGDF มีอัลกอริทึมที่ มีจุดตัดน้อยกว่าและเร็วกว่า Graphviz
จากประสบการณ์ของผม ผลลัพธ์ของ OGDF ดูสะอาดกว่ามาก
ดูประวัติ PR ที่เกี่ยวข้องได้ที่ GitHub ลิงก์
น่าสนใจดี อยากรู้ว่า รันตัวอย่าง ยังไง
จุดที่ดีของโปรเจกต์นี้คือมัน รองรับการสำรวจแบบอินเทอร์แอ็กทีฟโดยตั้งต้นจากสภาพแวดล้อมเว็บไคลเอนต์
เพราะเป็น layout ที่ออกแบบมาสำหรับ control flow graph (CFG) จึงทำ visualization ที่ปรับตามโดเมน ได้
Graphviz เองก็มีฟีเจอร์ polyline และการควบคุมลำดับ edge แต่เอกสารยังไม่ค่อยดี
น่าจะดีถ้ารวม อัลกอริทึม edge routing ของ Brandes และ Kopf เข้าไป
Graphviz เป็นโปรเจกต์ที่มีอายุเกือบ 40 ปีแล้ว และตอนนี้มีอาสาสมัครรุ่นที่สองไม่กี่คนดูแลอยู่
การสร้างเครื่องมือเป็นตลาดที่ยากเสมอ และผู้ใช้ก็มักเป็นคนเก่งแต่ทำงานอยู่ใน แผนกที่งบจำกัด
น่าเสียดายที่ พัฒนาการของเครื่องมือไดอะแกรม 2D แบบประกาศเชิงบรรยายยังช้ามาก
ใครก็ตามที่ทำงานในสายนี้ขอ +1 เป็นกำลังใจ เสมอ
ผมเองก็เคยใช้ mermaid และ graphviz แต่สุดท้ายก็กลับไปหา FigJam — เพราะอ่านง่ายและงานภาพสวยกว่า
graphviz เป็น ไบนารีขนาดใหญ่ ส่วน mermaid ก็ผูกกับ การเรนเดอร์ SVG ในเบราว์เซอร์ เลยใช้งานไม่ค่อยสะดวก
แค่อยากได้เครื่องมือที่ ทำไดอะแกรมจากข้อความได้ง่าย ๆ
แนวทางที่ผู้เขียนเสนอจึงดูเป็นความพยายามที่ดีในการควบคุม จุดสมดุลนี้
ถ้าไม่นับเรื่องที่ยังไม่จัดการลูป ก็ถือว่าน่าพอใจ
เอาต์พุตแบบ SVG/HTML มีข้อดีตรงที่แก้สไตล์และคัดลอกได้ง่าย
ถ้าอยากได้เครื่องมือไดอะแกรมแบบข้อความ ขอแนะนำ TikZ
ดู วิกิของ TikZ
แต่แน่นอนว่ามันไม่มี visual feedback แบบทันทีทันใด เหมือน FigJam
ผมไม่ค่อยชอบ dependency ที่เยอะเกินไปและความไม่สม่ำเสมอของโค้ด ใน mermaid
ส่วน nomnoml(ลิงก์) โค้ดสะอาดดี และยังมี graphre(ลิงก์) ที่พอร์ตเป็น Typescript ด้วย
แต่ถ้าจะใช้ mermaid กับ resvg-js ก็ต้องมีการรีแฟกเตอร์เรื่อง การวัดความกว้างข้อความใน SVG