บทที่ 13 การเพิ่มประสิทธิภาพการเขียนชุดคำสั่งใน VB.NET
เป็นภาคต่อของบทที่ 7
การเพิ่มประสิทธิภาพการเขียนชุดคำสั่งใน VB.NET
1. คลาส Stopwatch
ในคลาส Stopwatch จะเป็นแหล่งรวมของเมธอดที่ใช้ในการจับเวลาการประมวลผลของซีพียูซึ่งจะบอกเป็นหน่วยมินลิวินาที
โดยจะสามารถเข้าถึงหรือเรียกใช้เมธอด Start() และ Stop()
ซึ่งจะแจ้งผลค่าเวลาทางคุณสมบัติ ElapsedMilliseconds
ในคลาสนี้จะอยู่ในเนมสเปซ System.Diagnostics ดังนั้นการใช้งานจะต้องใช้คำสั่ง Import เข้ามาก่อน
ซึ่งจะประกาศไว้ส่วนบนของคลาส
|1| Imports System.Diagnostics
|2| Public Class Form1
|3|
|4| End Class
ในตัวอย่างต่อไปนี้จะเป็นการจับเวลาของคำสั่งการทำซ้ำ
เช่น การทำซ้ำ 1
ล้านรอบเวลารวมคือกี่มินลิวินาทีนั้นคือความสามารถของซีพียูในการประมวลผล
(1)
ให้อออกแบบหน้าจอ ส่วนชื่อของตัวควบคุมนั้นให้ใช้ค่าปริยายของตัวควบคุม
ดังภาพ
(2) ใช้คำสั่งทำซ้ำแบบ
For
ในการจับเวลาตามจำนวนรอบ จำนวนหนึ่งล้านรอบ
โดยไม่มีคำสั่งอะไรในการประมวลผลในการวนรอบ สังเกตจำนวนเวลาที่วนรอบ
|1| Imports System.Diagnostics
|2| Public Class Form1
|3| Private Sub Button1_Click(....)
Handles Button1.Click
|4| Dim objStopwatch As New Stopwatch
|5| Dim i As Double
|6| Dim s As String
|7| objStopwatch.Start()
|8| For i = 2 To 1000000
|9|
|10| Next
|11| objStopwatch.Stop()
|12| MsgBox(objStopwatch.ElapsedMilliseconds)
|13| End Sub
|14| End Class
บรรทัดที่ 1 คือการนำเข้าเนมสเปรช System.Diagnostics เพื่อให้เข้าถึงคลาส Stopwatch ได้
บรรทัดที่ 4 คือการสร้างตัวแปรออบเจ็กต์จากคลาส Stopwatch
บรรทัดที่ 7 คือเมธอดสำหรับสั่งให้เริ่มจับเวลา ณ ซีพียูเริ่มทำงาน
บรรทัดที่ 8 ถึง 10 คือการทำซ้ำแบบ For จำนวนหนึ่งล้านรอบโดยไม่มีชุดคำสั่งใดๆในคำสั่งนี้
บรรทัดที่ 11 คือ เมธอดสำหรับหยุดการจับเวลาการทำงานของซีพียู
บรรทัดที่ 12 คือ แสดงค่าเวลามีหน่วยเป็นมินลิวินาที ด้วยคุณสมบัติ ElapsedMilliseconds ทางกล่องข้อความ
บรรทัดที่ 4 คือการสร้างตัวแปรออบเจ็กต์จากคลาส Stopwatch
บรรทัดที่ 7 คือเมธอดสำหรับสั่งให้เริ่มจับเวลา ณ ซีพียูเริ่มทำงาน
บรรทัดที่ 8 ถึง 10 คือการทำซ้ำแบบ For จำนวนหนึ่งล้านรอบโดยไม่มีชุดคำสั่งใดๆในคำสั่งนี้
บรรทัดที่ 11 คือ เมธอดสำหรับหยุดการจับเวลาการทำงานของซีพียู
บรรทัดที่ 12 คือ แสดงค่าเวลามีหน่วยเป็นมินลิวินาที ด้วยคุณสมบัติ ElapsedMilliseconds ทางกล่องข้อความ
(3)
เมื่อรันและแสดงผลจะได้ค่าเวลาซึ่งแต่ละเครื่องที่รันโปรแกรมอาจจะได้ผลที่ต่างกันบ้างเล็กน้อยตามแต่ความเร็วของซีพียู
หน่วยเป็นมินลิวินาที ดังภาพ
(3) จากนั้นให้เพิ่มการประมวลผลโดยในทุกรอบให้เก็บคำว่า
“รักษ์เลย” ในบรรทัดที่ 9 เข้าไปทุกรอบ โดยการเพิ่มและแก้ไขคำสั่งในบรรทัดที่
8 9 12 สังเกตจำนวนเวลาที่วนรอบ (อย่าลืมแก้ไขจำนวนรอบเป็นเพียง 10,000 รอบเท่านั้น มิฉะนั้นโปรแกรมอาจจะหยุดค้างได้) โดยเขียนโค้ดดังนี้
|1| Imports System.Diagnostics
|2| Public Class Form1
|3| Private Sub Button1_Click(....)
Handles Button1.Click
|4| Dim objStopwatch As New Stopwatch
|5| Dim i As Double
|6| Dim s As String
|7| objStopwatch.Start()
|8| For i = 1 To 10000
|9| s = s & "รักษ์เลย" & i & vbCrLf
|10| Next
|11| objStopwatch.Stop()
|12| TextBox1.Text = s
|13|
MsgBox(objStopwatch.ElapsedMilliseconds)
|14| End Sub
|15|
End Class
บรรทัดที่ 6
คือการประกาศตัวแปร
S ชนิด String
บรรทัดที่ 9 คือการเชื่อมสตริงพร้อมตัดบรรทัดในทุกๆการวนรอบ
บรรทัดที่ 9 คือการเชื่อมสตริงพร้อมตัดบรรทัดในทุกๆการวนรอบ
(4) จากนั้นเมื่อรันโปรแกรมแล้วกดปุ่ม Test For จะมีการวนรอบคำว่า “รักษ์เลย” จำนวนหนึ่งหมึ่นแถวและแสดงจำนวนเวลาหน่วยเป็นมินลิวินาที
ในที่นี้คือ 780 มินลิวินาที
(5)
หากนักศึกษาทดสอบการทำซ้ำจากหนึ่งหมื่นรอบเป็นหนึ่งแสนรอบจะเห็นการหยุดค้างของโปรแกรมในขณะที่
ซีพียูไม่สามารถประมวลผล Process
อื่นได้ ด้วยปัญหานี้การเชื่อมสตริงโดยวิธีการทั่วไปจึงเกิดปัญหาเมื่อข้อมูลมีมากขึ้น
ดังนั้น .NET จึงได้มีคลาส StringBuilder เพื่อแก้ปัญหาดังกล่าว
2. คลาส StringBuilder
การจะเรียกใช้คลาสนี้จะต้องนำเข้าเนมสเปรซ
System.Text
เข้ามาจึงจะสามารถใช้คลาส StringBuilder
ได้ในตัวอย่างต่อไปนี้จะขอต่อเนื่องจากตัวอย่างที่ผ่านมาเป็นตัวทดสอบ
(1)
แก้ไขและเพิ่มคำสั่งในบรรทัดที่ 2 7 10 และ
13 ดังนี้
|1| Imports System.Diagnostics
|2| Imports System.Text
|3| Public Class Form1
|4| Private Sub Button1_Click(....)
Handles Button1.Click
|5| Dim objStopwatch As New Stopwatch
|6| Dim i As Double
|7| Dim s As new StringBuilder
|8| objStopwatch.Start()
|9| For i = 1 To 10000
|10| s.AppendLine("รักษ์เลย" & i)
|11| Next
|12| objStopwatch.Stop()
|13| TextBox1.Text
= s.ToString
|14|
MsgBox(objStopwatch.ElapsedMilliseconds)
|15| End Sub
|16| End Class
(2) จากนั้นเมื่อรันโปรแกรมแล้วกดปุ่ม Test For จะเห็นว่าในหนึ่งหมื่นรอบจะใช้เวลาเพียง 11 มินลิวินาทีเท่านั้น ซึ่งจากเดิมที่ใช้การเชื่อมต่อสตริงโดยทั่วไปจะใช้เวลาถึง
780 มินลิวินาที
(3) ปรับจำนวนการวนรอบให้เท่ากับหนึ่งแสนรอบ หรือ
หนึ่งล้านรอบสังเกตเวลาที่แสดงผลไม่แตกต่างกันมากนัก (เหตุที่มีความหน่วงอยู่เนื่องจากการส่งค่าตัวอักษรจำนวนหลายบรรทัดไปยัง
Textbox
จะต้องใช้เวลา)
2. เมธอด DoEvents()
จะพบว่าการเขียนโปรแกรมหากมีการทำซ้ำโดยมีชุดคำสั่งที่ทำให้ซีพียูประมวลหนักๆ
จะทำให้ซีพียูไม่ยอมทำงานอื่นใน Application นั้น (Not Responding) การแก้ไขปัญหานี้จะต้องใช้เมธอด Doevent() เพื่อสั่งให้ซีพียูยอมทำงานอื่นได้ แต่สำหรับการทำเช่นนี้จะพบกว่าระยะเวลาในการทำซ้ำจะมากขึ้น
ดังนั้นการคิดกระบวนการแก้ไขปัญหา (Algorithm)
แทนการใช้เมธอด DoEvent() จะเป็นสิ่งที่ดีกว่า
รูปแบบคือ Application.DoEvents()
(1) เพิ่มเมธอด DoEvents() เข้าไปในบรรทัดที่ 11 จากนั้นทดสอบโปรแกรมจะพบว่าโปรแกรมไม่หยุดค้าง
ดังนี้
|1| Imports System.Diagnostics
|2| Imports System.Text
|3| Public Class Form1
|4| Private Sub Button1_Click(....)
Handles Button1.Click
|5| Dim objStopwatch As New Stopwatch
|6| Dim i As Double
|7| Dim s As new StringBuilder
|8| objStopwatch.Start()
|9| For i = 1 To 1000000
|10| s.AppendLine("รักษ์เลย" & i)
|11| Application.DoEvents()
|12| Next
|13| objStopwatch.Stop()
|14| TextBox1.Text =
s.ToString
|15|
MsgBox(objStopwatch.ElapsedMilliseconds)
|16| End Sub
|17| End Class
(2) เมื่อรันโปรแกรมในการทำซ้ำหนึ่งล้านรอบ
แล้วลงขยับฟอร์มขณะรันจะสั่งเกตว่าสามารถใช้งานได้
และสังเกตเวลาในการทำซ้ำที่เพิ่มขึ้น
3. การตรวจจับข้อผิดพลาด
โดยคำสั่ง Try… Catch
หากมีคำสั่งที่มีข้อผิดพลาด
(Invalid)
ในขณะที่รันโปรแกรมในเครื่องผู้ใช้จะทำให้โปรแกรมปิดตัวเองลงไปโดยอัตโนมัติ
ซึ่งไม่ควรจะเกิดขึ้นในการพัฒนาโปรแกรม
(1)
จากตัวอย่างคือการส่งค่าสตริง ไปให้ integer ซึ่งไม่สามารถส่งค่าได้
(2) จากเขียนคำสั่ง Try Catch เพื่อดักจับข้อผิดพลาด
ดังนี้
(3) จากนั้นรันโปรแกรมจะพบการแจ้งรายละเอียดข้อผิดพลาดซึ่งโปรแกรมก็ยังสามารถทำงานอื่นได้
ความคิดเห็น
แสดงความคิดเห็น