ผู้แต่ง: Rob Howard การแปล: ปลาเขตร้อน
บทความนี้กล่าวถึง:
· เคล็ดลับทั่วไปเกี่ยวกับประสิทธิภาพ ASP.NET
· คำแนะนำและเคล็ดลับที่เป็นประโยชน์ในการปรับปรุงประสิทธิภาพ ASP.NET
· คำแนะนำสำหรับการใช้ฐานข้อมูลใน ASP.NET
· แคชและการประมวลผลพื้นหลังใน ASP.NET
การเขียนเว็บแอปพลิเคชันโดยใช้ ASP.NET นั้นง่ายมากอย่างเหลือเชื่อ ง่ายมากจนนักพัฒนาจำนวนมากไม่ต้องใช้เวลาในการสร้างแอปพลิเคชันของตนให้ทำงานได้ดี ในบทความนี้ ผมขอแนะนำเคล็ดลับ 10 ข้อในการเขียนเว็บแอปพลิเคชันประสิทธิภาพสูง ฉันจะไม่จำกัดการสนทนาของฉันอยู่เพียงแอปพลิเคชัน ASP.NET เนื่องจากแอปพลิเคชัน ASP.NET เป็นเพียงส่วนย่อยของแอปพลิเคชันเว็บเท่านั้น บทความนี้ไม่ได้มีจุดมุ่งหมายเพื่อเป็นแนวทางขั้นสุดท้ายในการเพิ่มประสิทธิภาพการทำงานของเว็บแอปพลิเคชัน - หนังสือทั้งเล่มสามารถทำเช่นนั้นได้อย่างง่ายดาย เราควรถือว่าบทความนี้เป็นจุดเริ่มต้นที่ดีแทน
ก่อนที่ฉันจะกลายเป็นคนบ้างาน ฉันจะไปปีนเขาบ่อยๆ ก่อนจะปีนอะไรก็ตาม ฉันชอบดูเส้นทางในไกด์นำเที่ยวและอ่านคำแนะนำจากผู้ที่เคยไปยอดเขา แต่ไม่ว่าหนังสือนำเที่ยวจะเขียนออกมาดีแค่ไหน คุณจำเป็นต้องมีประสบการณ์การปีนเขาจริงก่อนที่จะพยายามบรรลุเป้าหมายที่ท้าทาย ในทำนองเดียวกัน คุณสามารถเรียนรู้วิธีเขียนแอปพลิเคชันเว็บประสิทธิภาพสูงได้ก็ต่อเมื่อต้องเผชิญกับการแก้ไขปัญหาด้านประสิทธิภาพหรือใช้งานไซต์ที่มีปริมาณงานสูง
ประสบการณ์ส่วนตัวของฉันมาจากการทำงานเป็น Foundation Program Manager ในทีม ASP.NET ที่ Microsoft ดูแลและจัดการ www.asp.net และช่วยเหลือสถาปนิก Community Server ซึ่งเป็นหนึ่งในแอปพลิเคชัน ASP.NET ที่มีชื่อเสียง (ASP.NET Forums , .Text และ nGallery เชื่อมต่อกับแพลตฟอร์มเดียว) ฉันแน่ใจว่าเคล็ดลับบางส่วนที่ช่วยฉันได้ก็จะเป็นประโยชน์กับคุณเช่นกัน
คุณควรพิจารณาแยกแอปพลิเคชันของคุณออกเป็นหลายเลเยอร์เชิงตรรกะ คุณอาจเคยได้ยินเกี่ยวกับสถาปัตยกรรม 3 ระดับ (หรือ n ระดับ) สิ่งเหล่านี้มักจะกำหนดรูปแบบโครงสร้างที่แบ่งธุรกิจและ/หรือฮาร์ดแวร์ออกเป็นแผนกการทำงาน หากระบบต้องการสเกลที่ใหญ่ขึ้น ก็สามารถเพิ่มฮาร์ดแวร์ได้มากขึ้นได้อย่างง่ายดาย อย่างไรก็ตาม นั่นจะทำให้เกิดการเสื่อมประสิทธิภาพที่เกี่ยวข้องกับการข้ามธุรกิจและเครื่องจักร ดังนั้นเราจึงควรหลีกเลี่ยง ดังนั้นทุกครั้งที่เป็นไปได้ ให้ลองเรียกใช้เพจ ASP.NET และส่วนประกอบที่เกี่ยวข้องของเพจในแอปพลิเคชันเดียวกัน
เนื่องจากการแยกโค้ดและขอบเขตระหว่างเลเยอร์ การใช้บริการเว็บหรือระยะไกลจึงสามารถลดประสิทธิภาพลงได้ 20% หรือมากกว่า
ชั้นข้อมูลจะแตกต่างกันเล็กน้อย เนื่องจากโดยทั่วไปแล้ว ควรมีฮาร์ดแวร์สำหรับฐานข้อมูลโดยเฉพาะจะดีกว่า อย่างไรก็ตาม ต้นทุนของกระบวนการกระโดดไปยังฐานข้อมูลยังคงสูง ดังนั้นประสิทธิภาพในชั้นข้อมูลจึงควรพิจารณาเป็นอันดับแรกเมื่อเพิ่มประสิทธิภาพโค้ดของคุณ
ก่อนที่จะลงทุนในการแก้ไขปัญหาประสิทธิภาพของแอปพลิเคชันของคุณ ตรวจสอบให้แน่ใจว่าคุณได้วิเคราะห์แอปพลิเคชันของคุณเพื่อค้นหาสาเหตุของปัญหา ตัวนับประสิทธิภาพหลัก (เช่นตัวที่ระบุเปอร์เซ็นต์ของเวลาที่ใช้ในการรวบรวมขยะ) ยังมีประโยชน์อย่างมากในการค้นหาว่าแอปพลิเคชันใช้เวลาส่วนใหญ่ไปที่ใด แม้ว่าสถานที่เหล่านั้นที่ใช้เวลามักจะไม่ค่อยสัญชาตญาณก็ตาม
ในบทความนี้ ฉันพูดถึงสองวิธีในการปรับปรุงประสิทธิภาพ: การเพิ่มประสิทธิภาพขนาดใหญ่ เช่น การใช้แคช ASP.NET และการเพิ่มประสิทธิภาพขนาดเล็ก ซึ่งมักเกิดขึ้นซ้ำๆ การเพิ่มประสิทธิภาพเล็กๆ น้อยๆ เหล่านี้บางครั้งก็น่าสนใจที่สุด การเปลี่ยนแปลงเล็กๆ น้อยๆ ที่คุณทำกับโค้ดของคุณจะถูกเรียกเป็นพันครั้ง ปรับชิ้นส่วนขนาดใหญ่ให้เหมาะสมและคุณอาจพบว่าประสิทธิภาพโดยรวมเพิ่มขึ้นอย่างมาก ด้วยการเพิ่มประสิทธิภาพในส่วนเล็กๆ คุณอาจลดเวลาสักสองสามไมโครวินาทีจากคำขอที่กำหนด แต่เมื่อสะสมในคำขอทั้งหมดต่อวัน คุณจะได้รับการปรับปรุงประสิทธิภาพอย่างไม่คาดคิด
ประสิทธิภาพในชั้นข้อมูล
เมื่อคุณเริ่มปรับประสิทธิภาพของแอปพลิเคชันให้เหมาะสม มีการทดสอบชี้ขาดประการหนึ่งที่คุณสามารถจัดลำดับความสำคัญได้: โค้ดจำเป็นต้องเข้าถึงฐานข้อมูลหรือไม่ ถ้าเป็นเช่นนั้น คุณไปบ่อยแค่ไหน? โปรดทราบว่าการทดสอบนี้สามารถนำไปใช้กับโค้ดที่ใช้บริการเว็บหรือการควบคุมระยะไกลได้ แต่ฉันจะไม่ครอบคลุมสิ่งเหล่านั้นในบทความนี้
หากจำเป็นต้องมีคำขอฐานข้อมูลในเส้นทางโค้ดบางเส้นทางในโค้ดของคุณ และคุณพบตำแหน่งอื่นๆ ที่คุณต้องการจัดลำดับความสำคัญของการปรับให้เหมาะสม เช่น การจัดการสตริง ให้หยุดและทำการทดสอบที่สำคัญก่อน เว้นแต่คุณจะมีปัญหาด้านประสิทธิภาพที่แย่มากที่ต้องจัดการ เวลาของคุณจะถูกนำไปใช้ในการเพิ่มประสิทธิภาพเวลาที่ใช้ในการเชื่อมต่อกับฐานข้อมูล ปริมาณข้อมูลที่ส่งคืน และการดำเนินการที่คุณทำกับและจากฐานข้อมูล
ตอนนี้ฉันได้กล่าวถึงข้อมูลโดยทั่วไปแล้ว เรามาดูเคล็ดลับ 10 ข้อเพื่อช่วยให้แอปพลิเคชันของคุณทำงานได้ดีขึ้นกัน ฉันจะเริ่มต้นด้วยสิ่งที่มีผลกระทบที่ชัดเจนที่สุดในการปรับปรุงประสิทธิภาพ
เคล็ดลับที่ 1 - ส่งกลับชุดผลลัพธ์หลายชุด
ดูโค้ดฐานข้อมูลของคุณเพื่อดูว่าคุณมีเส้นทางคำขอที่เข้าถึงฐานข้อมูลมากกว่าหนึ่งครั้งหรือไม่ การเดินทางไปกลับแต่ละครั้งจะลดจำนวนคำขอที่แอปพลิเคชันของคุณสามารถให้บริการได้ต่อวินาที ด้วยการส่งคืนชุดผลลัพธ์หลายชุดในคำขอฐานข้อมูลเดียว คุณสามารถลดเวลาโดยรวมที่ใช้โดยการสื่อสารฐานข้อมูลได้ หลังจากที่คุณลดจำนวนคำขอที่เซิร์ฟเวอร์ฐานข้อมูลของคุณต้องจัดการแล้ว คุณยังทำให้ระบบของคุณสามารถปรับขนาดได้มากขึ้นอีกด้วย
โดยทั่วไปคุณสามารถใช้คำสั่ง SQL แบบไดนามิกเพื่อส่งคืนชุดผลลัพธ์หลายชุดได้ ฉันชอบใช้กระบวนงานที่เก็บไว้ เป็นที่ถกเถียงกันอยู่ว่าคุณควรใส่ตรรกะทางธุรกิจไว้ในขั้นตอนการจัดเก็บหรือไม่ แต่ฉันคิดว่าตรรกะในขั้นตอนการจัดเก็บสามารถจำกัดข้อมูลที่ส่งคืนได้ (ลดขนาดของชุดข้อมูล เวลาที่ใช้ในการเชื่อมต่อเครือข่าย และลดความจำเป็นในการ กรองข้อมูลเลเยอร์ตรรกะ) ก็เป็นสิ่งที่ดี
การใช้อินสแตนซ์ SqlCommand และเมธอด ExecuteReader เพื่อสร้างคลาสธุรกิจที่พิมพ์อย่างยิ่ง คุณสามารถย้ายตัวชี้ชุดผลลัพธ์ไปข้างหน้าได้โดยการเรียก NextResult รูปที่ 1 แสดงเซสชันตัวอย่างที่ใช้คลาสที่กำหนดเพื่อสร้าง ArrayLists หลายรายการ การส่งคืนเฉพาะข้อมูลที่คุณต้องการจากฐานข้อมูลจะช่วยลดคำขอหน่วยความจำบนเซิร์ฟเวอร์ของคุณได้อย่างมาก
1// อ่านชุดผลลัพธ์แรก
2reader = command.ExecuteReader();
3
4// อ่านข้อมูลจากชุดผลลัพธ์นั้น
5 ในขณะที่ (reader อ่าน ()) {
ซัพพลายเออร์ 6 รายเพิ่ม (PopulateSupplierFromIDataReader (เครื่องอ่าน));
7}
8
9// อ่านชุดผลลัพธ์ถัดไป
10reader.NextResult();
11
12// อ่านข้อมูลจากชุดผลลัพธ์ที่สองนั้น
13 ในขณะที่ (reader อ่าน ()) {
14 ผลิตภัณฑ์เพิ่ม(PopulateProductFromIDataReader(reader));
15}
16
17
เคล็ดลับ 2 - การเข้าถึงข้อมูลแบบแบ่งหน้า
DataGrid ของ ASP.NET มอบความสามารถที่ยอดเยี่ยม: รองรับการเพจข้อมูล เมื่อตั้งค่าการแบ่งหน้าใน DataGrid จำนวนผลลัพธ์ที่ระบุจะแสดงในแต่ละครั้ง นอกจากนี้ UI การเพจสำหรับการนำทางระหว่างผลลัพธ์จะแสดงที่ด้านล่างของ DataGrid UI แบบแบ่งหน้าช่วยให้คุณสามารถนำทางไปข้างหน้าหรือย้อนกลับผ่านข้อมูลที่แสดง โดยแสดงผลลัพธ์จำนวนหนึ่งต่อหน้า
แต่มีปัญหาเล็กน้อย เมื่อใช้ DataGrid สำหรับเพจ ข้อมูลทั้งหมดจะต้องผูกไว้กับตาราง ตัวอย่างเช่น ชั้นข้อมูลของคุณจะต้องส่งคืนข้อมูลทั้งหมด จากนั้น DataGrid จะต้องเติมข้อมูลระเบียนทั้งหมดที่จะแสดงตามหน้าปัจจุบัน หากส่งคืนระเบียน 100,000 รายการเมื่อคุณใช้การแบ่งหน้า DataGrid ระเบียน 99,975 รายการจะถูกละทิ้งต่อคำขอ (สมมติว่าความจุของแต่ละหน้าคือ 25 ระเบียน) เมื่อจำนวนเรกคอร์ดเพิ่มขึ้น ประสิทธิภาพของแอปพลิเคชันจะได้รับผลกระทบอย่างมาก เนื่องจากต้องส่งคืนข้อมูลมากขึ้นเรื่อยๆ พร้อมคำขอแต่ละรายการ
วิธีหนึ่งในการเขียนโค้ดการแบ่งหน้าที่ดีขึ้นคือการใช้กระบวนงานที่เก็บไว้ รูปที่ 2 แสดงตัวอย่างขั้นตอนการจัดเก็บที่เพจตารางข้อมูลคำสั่งซื้อในฐานข้อมูล Nothwind โดยพื้นฐานแล้ว สิ่งที่คุณต้องทำคือส่งผ่านดัชนีของเพจและความจุของเพจ ฐานข้อมูลจะคำนวณชุดผลลัพธ์ที่เหมาะสมและส่งกลับ
1สร้างขั้นตอน northwind_OrdersPaged
2(
3 @PageIndex int,
4 @ขนาดหน้า int
5)
6AS
7เริ่มต้น
8DECLARE @PageLowerBound int
9DECLARE @PageUpperBound int
10ประกาศ @RowsToReturn int
11
12-- ขั้นแรกให้ตั้งค่าการนับแถว
13SET @RowsToReturn = @PageSize * (@PageIndex + 1)
14ตั้งค่าจำนวนแถว @RowsToReturn
15
16--กำหนดขอบเขตหน้า
17SET @PageLowerBound = @PageSize * @PageIndex
18SET @PageUpperBound = @PageLowerBound + @PageSize + 1
19
20-- สร้างตารางชั่วคราวเพื่อจัดเก็บผลลัพธ์ที่เลือก
21สร้างตาราง #PageIndex
ยี่สิบสอง(
23 IndexId int IDENTITY (1, 1) ไม่เป็นโมฆะ
24 รหัสคำสั่งซื้อ int
25)
26
27--ใส่ลงในตารางอุณหภูมิ
28ใส่ #PageIndex (รหัสคำสั่งซื้อ)
29เลือก
30 รหัสคำสั่งซื้อ
31จาก
32 คำสั่งซื้อ
33เรียงลำดับตาม
34 รหัสคำสั่งซื้อ DESC
35
36--ส่งคืนจำนวนรวม
37เลือกนับ(รหัสคำสั่งซื้อ) จากคำสั่งซื้อ
38
39-- กลับผลลัพธ์เพจ
40เลือก
41 อ.*
42FROM
43 คำสั่งโอ้
44 #ดัชนีหน้า ดัชนีหน้า
45ที่ไหน
46 O.OrderID = PageIndex.OrderID และ
47 PageIndex.IndexID > @PageLowerBound และ
48 PageIndex.IndexID < @PageUpperBound
49เรียงลำดับตาม
50 PageIndex.IndexID
51
52END
53
54
ในช่วงระยะเวลาการบริการชุมชน เราได้เขียนการควบคุมเซิร์ฟเวอร์เพจจิ้งเพื่อทำเพจข้อมูลเหล่านี้ คุณจะสังเกตเห็นว่าฉันใช้แนวคิดที่กล่าวถึงในเคล็ดลับที่ 1 เพื่อส่งคืนชุดผลลัพธ์สองชุดจากขั้นตอนการจัดเก็บ: จำนวนบันทึกทั้งหมดและข้อมูลที่ร้องขอ
จำนวนบันทึกทั้งหมดที่ส่งคืนอาจแตกต่างกันไปขึ้นอยู่กับคำขอที่ดำเนินการ ตัวอย่างเช่น สามารถใช้ส่วนคำสั่ง WHERE เพื่อจำกัดข้อมูลที่ส่งคืนได้ เราต้องทราบจำนวนระเบียนทั้งหมดที่จะส่งคืนเพื่อคำนวณจำนวนหน้าทั้งหมดที่จะแสดงใน UI ที่มีการแบ่งหน้า ตัวอย่างเช่น หากมีเรกคอร์ดทั้งหมด 1,000,000 เรกคอร์ด และส่วนคำสั่ง WHERE ถูกใช้เพื่อกรองเรกคอร์ดเหล่านั้นเป็น 1,000 เรกคอร์ด ตรรกะการเพจจำเป็นต้องทราบจำนวนเรกคอร์ดทั้งหมดเพื่อส่ง UI การเพจอย่างเหมาะสม
เคล็ดลับ 3 - การรวมการเชื่อมต่อ
การสร้างการเชื่อมต่อ TCP ระหว่างเว็บแอปพลิเคชันของคุณกับ SQL Server อาจเป็นการดำเนินการที่มีราคาแพง นักพัฒนาที่ Microsoft ใช้การรวมการเชื่อมต่อมาระยะหนึ่งแล้ว ทำให้พวกเขาสามารถนำการเชื่อมต่อกับฐานข้อมูลกลับมาใช้ใหม่ได้ แทนที่จะสร้างการเชื่อมต่อ TCP ใหม่สำหรับแต่ละคำขอ การเชื่อมต่อใหม่จะถูกสร้างขึ้นเฉพาะเมื่อไม่มีการเชื่อมต่อที่พร้อมใช้งานในกลุ่มการเชื่อมต่อ เมื่อการเชื่อมต่อปิด การเชื่อมต่อจะถูกส่งกลับไปยังพูลการเชื่อมต่อ โดยยังคงรักษาการเชื่อมต่อกับฐานข้อมูล แทนที่จะทำลายการเชื่อมต่อ TCP โดยสมบูรณ์
แน่นอนคุณต้องระมัดระวังเกี่ยวกับการเชื่อมต่อที่รั่วไหล ปิดการเชื่อมต่อของคุณเสมอเมื่อคุณใช้งานเสร็จแล้ว ฉันทำซ้ำ: ไม่ว่าใครจะพูดอะไรเกี่ยวกับกลไกการรวบรวมขยะของ Microsoft .NET Framework คุณต้องเรียกเมธอด Close หรือ Dispose ในการเชื่อมต่อของคุณอย่างชัดเจนเสมอเมื่อคุณดำเนินการเสร็จแล้ว อย่าเชื่อถือ Common Language Runtime (CLR) เพื่อล้างข้อมูลและปิดการเชื่อมต่อให้คุณตามเวลาที่กำหนดไว้ ในที่สุด CLR จะทำลายคลาสและบังคับให้ปิดการเชื่อมต่อ แต่คุณไม่รับประกันว่าเมื่อใดที่กลไกการรวบรวมขยะบนวัตถุจะถูกดำเนินการจริง
เพื่อให้ได้ผลลัพธ์ที่ดีที่สุดโดยใช้การรวมการเชื่อมต่อ คุณต้องปฏิบัติตามกฎสองสามข้อ ขั้นแรก ให้เปิดการเชื่อมต่อ ทำงาน จากนั้นจึงปิดการเชื่อมต่อ ไม่เป็นไรหากคุณต้อง (ควรใช้เคล็ดลับที่ 1) เปิดและปิดการเชื่อมต่อหลายๆ ครั้งต่อคำขอ จะดีกว่าการเปิดการเชื่อมต่อทิ้งไว้แล้วส่งต่อไปยังวิธีการต่างๆ หลายวิธี ประการที่สอง ใช้สตริงการเชื่อมต่อเดียวกัน (และแน่นอนว่าต้องใช้ ID เธรดเดียวกัน หากคุณใช้การรับรองความถูกต้องแบบรวม) หากคุณไม่ได้ใช้สตริงการเชื่อมต่อเดียวกัน เช่น สตริงการเชื่อมต่อแบบกำหนดเองที่แตกต่างกันโดยอิงตามผู้ใช้ที่เข้าสู่ระบบ คุณจะไม่ได้รับค่าที่เหมาะสมที่สุดแบบเดียวกับที่พูลการเชื่อมต่อให้มา และหากคุณใช้การรับรองความถูกต้องแบบรวมเมื่อแอบอ้างเป็นผู้ใช้จำนวนมาก พูลการเชื่อมต่อของคุณก็จะมีประสิทธิภาพน้อยลงเช่นกัน ตัวนับประสิทธิภาพข้อมูล .NET CLR จะมีประโยชน์เมื่อพยายามติดตามปัญหาด้านประสิทธิภาพใดๆ ที่เกี่ยวข้องกับการรวมพูลการเชื่อมต่อ
เมื่อใดก็ตามที่แอปพลิเคชันของคุณเชื่อมต่อกับทรัพยากร เช่น ฐานข้อมูล หรือทำงานในกระบวนการอื่น คุณควรดำเนินการนี้โดยเน้นไปที่เวลาที่ใช้ในการเชื่อมต่อกับทรัพยากร เวลาที่ใช้ในการส่งและรับข้อมูล และเวลาที่ใช้ ใช้ในการส่งและรับข้อมูล มีการเดินทางไปกลับฐานข้อมูลหลายครั้งเพื่อปรับให้เหมาะสม การเพิ่มประสิทธิภาพกระบวนการใดๆ ในแอปพลิเคชันของคุณเป็นขั้นตอนแรกในการเริ่มได้รับประสิทธิภาพที่ดีขึ้น
ชั้นแอปพลิเคชันประกอบด้วยตรรกะที่เชื่อมต่อกับชั้นข้อมูลของคุณและแปลงข้อมูลให้เป็นอินสแตนซ์คลาสและกระบวนการทางลอจิคัลที่มีความหมาย ตัวอย่างเช่น ในเซิร์ฟเวอร์ชุมชน นี่คือที่ที่คุณสร้างฟอรัมหรือคอลเล็กชันเธรด และใช้กฎทางธุรกิจ เช่น สิทธิ์ ที่สำคัญกว่านั้นคือที่ซึ่งตรรกะของการแคชถูกดำเนินการ
เคล็ดลับ 4 - ASP.NET Buffering API
สิ่งแรกที่ต้องพิจารณาก่อนที่คุณจะเริ่มเขียนโค้ดบรรทัดแรกในแอปพลิเคชันของคุณคือการออกแบบเลเยอร์แอปพลิเคชันเพื่อเพิ่มและใช้ประโยชน์จากคุณลักษณะการแคชของ ASP.NET
หากส่วนประกอบของคุณทำงานภายในแอปพลิเคชัน ASP.NET คุณเพียงแค่อ้างอิง System.Web.dll ในโครงการแอปพลิเคชันของคุณ เมื่อคุณต้องการเข้าถึงแคช ให้ใช้คุณสมบัติ HttpRuntime.Cache (ออบเจ็กต์นี้ยังสามารถเข้าถึงได้ผ่าน Page.Cache และ HttpContext.Cache)
มีแนวทางหลายประการสำหรับการใช้ข้อมูลที่แคชไว้ ประการแรก หากข้อมูลสามารถใช้ได้หลายครั้ง การแคชก็เป็นทางเลือกที่ดี ประการที่สอง หากข้อมูลเป็นแบบทั่วไปและไม่เฉพาะเจาะจงสำหรับคำขอหรือผู้ใช้เฉพาะ การแคชข้อมูลนั้นก็เป็นตัวเลือกที่ดี หากข้อมูลเป็นผู้ใช้หรือคำขอเฉพาะ แต่มีอายุการใช้งานยาวนาน ข้อมูลนั้นสามารถแคชได้แต่อาจไม่ได้ใช้บ่อย ประการที่สาม หลักการที่มักถูกมองข้ามคือบางครั้งคุณสามารถแคชได้มากเกินไป โดยทั่วไปในเครื่อง x86 เพื่อลดโอกาสที่จะเกิดข้อผิดพลาดหน่วยความจำไม่เพียงพอ คุณจะต้องเรียกใช้กระบวนการที่ใช้ไบต์ส่วนตัวไม่เกิน 800MB ดังนั้นการแคชควรถูกจำกัด กล่าวอีกนัยหนึ่ง คุณอาจจำเป็นต้องใช้ผลลัพธ์ของการคำนวณหนึ่งครั้งซ้ำ แต่หากการคำนวณนั้นต้องใช้พารามิเตอร์ 10 พารามิเตอร์ คุณอาจต้องพยายามแคชการเรียงสับเปลี่ยน 10 รายการ และนั่นอาจทำให้คุณประสบปัญหาได้ ข้อผิดพลาดหน่วยความจำไม่เพียงพอเนื่องจากการโอเวอร์แคชเป็นเรื่องปกติใน ASP.NET โดยเฉพาะกับชุดข้อมูลขนาดใหญ่
การแคชมีคุณสมบัติที่ยอดเยี่ยมหลายประการที่คุณต้องรู้ ขั้นแรก แคชใช้อัลกอริธึมที่ใช้ล่าสุด ซึ่งช่วยให้ ASP.NET บังคับให้แคชล้าง—ลบรายการที่ไม่ได้ใช้ออกจากแคชโดยอัตโนมัติ—เมื่อหน่วยความจำทำงานมีประสิทธิภาพน้อยลง ประการที่สอง แคชรองรับการขึ้นต่อกันที่หมดอายุแล้วซึ่งสามารถบังคับให้หมดอายุได้ การขึ้นต่อกันเหล่านี้รวมถึงเวลา คีย์ และไฟล์ มักใช้เวลา แต่ด้วย ASP.NET 2.0 จึงมีการแนะนำประเภทการทำให้ใช้ไม่ได้ใหม่และมีประสิทธิภาพยิ่งขึ้น: การทำให้แคชฐานข้อมูลใช้งานไม่ได้ หมายถึงการลบรายการในแคชโดยอัตโนมัติเมื่อข้อมูลในฐานข้อมูลเปลี่ยนแปลง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการทำให้แคชฐานข้อมูลใช้ไม่ได้ โปรดดูคอลัมน์ Dino Esposito Cutting Edge ในนิตยสาร MSDN ฉบับเดือนกรกฎาคม 2547 เพื่อทำความเข้าใจสถาปัตยกรรมของแคช โปรดดูรูปที่ 3
เคล็ดลับ 5 — การแคชตามคำขอ
ก่อนหน้านี้ในบทความนี้ ฉันได้กล่าวไว้ว่าการปรับปรุงเล็กๆ น้อยๆ ในเส้นทางโค้ดที่มีการข้ามบ่อยครั้งสามารถนำไปสู่ประสิทธิภาพโดยรวมที่เพิ่มขึ้นอย่างมาก จากการปรับปรุงเล็กๆ น้อยๆ เหล่านี้ มีสิ่งหนึ่งที่ฉันชอบที่สุดอย่างแน่นอน และฉันเรียกมันว่าการแคชตามคำขอ
API การแคชได้รับการออกแบบมาเพื่อแคชข้อมูลเป็นระยะเวลานานขึ้น หรือจนกว่าจะตรงตามเงื่อนไขบางประการ แต่การแคชต่อคำขอหมายถึงการแคชข้อมูลในช่วงเวลาของคำขอนั้นเท่านั้น สำหรับแต่ละคำขอ มีการเข้าถึงเส้นทางรหัสเฉพาะบ่อยครั้ง แต่ข้อมูลจะถูกแยก นำไปใช้ แก้ไข หรืออัปเดตเพียงครั้งเดียวเท่านั้น ฟังดูเป็นทฤษฎีเล็กน้อย ดังนั้นเรามายกตัวอย่างที่เป็นรูปธรรมกันดีกว่า
ในแอปพลิเคชันฟอรัมเซิร์ฟเวอร์ชุมชน การควบคุมเซิร์ฟเวอร์แต่ละรายการที่ใช้บนเพจต้องการข้อมูลการตั้งค่าส่วนบุคคลเพื่อกำหนดลักษณะที่ปรากฏที่จะใช้ ตารางสไตล์ใดที่จะใช้ และข้อมูลการตั้งค่าส่วนบุคคลอื่นๆ ข้อมูลบางส่วนนี้สามารถแคชได้ในระยะยาว แต่ข้อมูลบางส่วนจะถูกดึงมาเพียงครั้งเดียวต่อคำขอ จากนั้นจึงนำมาใช้ซ้ำหลายครั้งในระหว่างการร้องขอนั้น เช่น สำหรับลักษณะที่ปรากฏของตัวควบคุม
เพื่อให้บรรลุการแคชตามคำขอ ให้ใช้ ASP.NET HttpContext สำหรับแต่ละคำขอ อินสแตนซ์ HttpContext จะถูกสร้างขึ้นและสามารถเข้าถึงได้จากทุกที่ภายในคุณสมบัติ HttpContext.Current ในระหว่างการร้องขอ คลาส HttpContext มีคุณสมบัติคอลเลกชันรายการพิเศษ และข้อมูลที่เพิ่มในคอลเลกชันรายการนี้จะถูกแคชเฉพาะในช่วงระยะเวลาของการร้องขอ เช่นเดียวกับที่คุณสามารถใช้แคชเพื่อจัดเก็บข้อมูลที่เข้าถึงบ่อย คุณยังสามารถใช้ HttpContext.Items เพื่อจัดเก็บข้อมูลที่ใช้เฉพาะตามคำขอเท่านั้น ตรรกะเบื้องหลังนั้นง่ายมาก: ข้อมูลจะถูกเพิ่มลงในคอลเลกชัน HttpContext.Items เมื่อไม่มีอยู่ และในการค้นหาครั้งต่อๆ ไป จะมีเพียงข้อมูลใน HttpContext.Items เท่านั้นที่จะถูกส่งกลับ
เคล็ดลับ 6 — การประมวลผลเบื้องหลัง
Path to Code ควรเร็วที่สุดเท่าที่จะเป็นไปได้ใช่ไหม? อาจมีบางครั้งที่คุณพบว่าคุณกำลังดำเนินงานที่ใช้ทรัพยากรมากซึ่งดำเนินการกับทุกคำขอหรือทุกคำขอ n การส่งอีเมลหรือการวิเคราะห์และตรวจสอบข้อมูลขาเข้าเป็นเพียงตัวอย่างบางส่วน
เมื่อวิเคราะห์ ASP.NET Forums 1.0 และออกแบบสถาปัตยกรรมเนื้อหาที่ประกอบเป็นเซิร์ฟเวอร์ชุมชนใหม่ เราพบว่าเส้นทางโค้ดสำหรับการเผยแพร่โพสต์ใหม่นั้นช้ามาก ทุกครั้งที่มีการเผยแพร่โพสต์ใหม่ แอปพลิเคชันจะต้องตรวจสอบให้แน่ใจก่อนว่าไม่มีโพสต์ที่ซ้ำกัน จากนั้นจะต้องวิเคราะห์โพสต์โดยใช้ตัวกรอง "คำที่ไม่เหมาะสม" วิเคราะห์อิโมติคอนตัวละครของโพสต์ แท็กและจัดทำดัชนีโพสต์ และเพิ่ม โพสต์ไปยังคำขอเมื่อมีการร้องขอ เพิ่มลงในคิวที่เหมาะสม ตรวจสอบไฟล์แนบ และสุดท้ายส่งการแจ้งเตือนทางอีเมลไปยังสมาชิกทุกคนทันทีหลังจากเผยแพร่โพสต์ เห็นได้ชัดว่ามีส่วนเกี่ยวข้องมากมาย
หลังจากการวิจัยพบว่าเวลาส่วนใหญ่ถูกใช้ไปกับการจัดทำดัชนีตรรกะและการส่งอีเมล การโพสต์ดัชนีเป็นการดำเนินการที่ใช้เวลานานมากและพบว่าฟังก์ชัน System.Web.Mail ในตัวเชื่อมต่อกับเซิร์ฟเวอร์ SMTP แล้วส่งอีเมลอย่างต่อเนื่อง เมื่อจำนวนสมาชิกสำหรับโพสต์หรือหัวข้อเฉพาะเพิ่มขึ้น ฟังก์ชัน AddPost จะใช้เวลาดำเนินการนานขึ้นเรื่อยๆ
ไม่จำเป็นต้องจัดทำดัชนีอีเมลสำหรับทุกคำขอ ตามหลักการแล้ว เราต้องการรวมการดำเนินการนี้เข้าด้วยกัน โดยจัดทำดัชนีโพสต์ครั้งละ 25 โพสต์ หรือส่งอีเมลทั้งหมดทุกๆ ห้านาที เราตัดสินใจใช้โค้ดที่ฉันเคยใช้เพื่อสร้างต้นแบบการทำให้แคชข้อมูลใช้งานไม่ได้ซึ่งท้ายที่สุดก็รวมอยู่ใน Visual Studio 2005
คลาส Timer ในเนมสเปซ System.Threading มีประโยชน์มาก แต่ไม่ค่อยเป็นที่รู้จักใน .NET Framework อย่างน้อยก็ในหมู่นักพัฒนาเว็บ เมื่อสร้างแล้ว คลาส Timer นี้จะเรียกการเรียกกลับที่ระบุในช่วงเวลาที่กำหนดได้สำหรับเธรดใน ThreadPool ซึ่งหมายความว่าคุณสามารถตั้งค่าโค้ดของคุณให้ดำเนินการโดยไม่ต้องร้องขอขาเข้าไปยังแอปพลิเคชัน ASP.NET ซึ่งเหมาะสำหรับการประมวลผลในเบื้องหลัง คุณยังสามารถดำเนินการต่างๆ เช่น การจัดทำดัชนีหรือการส่งอีเมลในกระบวนการเบื้องหลังนี้ได้
อย่างไรก็ตาม มีปัญหาหลายประการเกี่ยวกับเทคโนโลยีนี้ หากถอนการติดตั้งโดเมนแอปพลิเคชัน อินสแตนซ์ตัวจับเวลานี้จะหยุดการทำงานของเหตุการณ์ นอกจากนี้ เนื่องจาก CLR มีมาตรฐานที่เข้มงวดสำหรับจำนวนเธรดต่อกระบวนการ อาจมีสถานการณ์ในเซิร์ฟเวอร์ที่มีการโหลดจำนวนมาก ซึ่งตัวจับเวลาอาจไม่รับประกันว่าเธรดจะดำเนินการต่อไปให้เสร็จสมบูรณ์ และในระดับหนึ่งอาจทำให้เกิดความล่าช้า . ASP.NET พยายามลดโอกาสของเหตุการณ์นี้ให้เหลือน้อยที่สุด โดยการรักษาจำนวนเธรดที่พร้อมใช้งานในกระบวนการ และใช้เพียงส่วนหนึ่งของเธรดทั้งหมดสำหรับการประมวลผลคำขอ อย่างไรก็ตาม นี่อาจเป็นปัญหาได้หากคุณมีการดำเนินการแบบอะซิงโครนัสจำนวนมาก
พื้นที่ไม่เพียงพอสำหรับโค้ดนี้ แต่คุณสามารถดาวน์โหลดตัวอย่างที่เข้าใจง่ายได้ที่ www.rob-howard.net ดูสไลด์และการสาธิตจากการนำเสนอของ Blackbelt TechEd 2004
เคล็ดลับ 7 — การแคชเอาต์พุตเพจและพร็อกซีเซิร์ฟเวอร์
ASP.NET คือเลเยอร์การนำเสนอของคุณ (หรือควรเป็นเลเยอร์การนำเสนอของคุณ) ประกอบด้วยเพจ การควบคุมผู้ใช้ การควบคุมเซิร์ฟเวอร์ (HttpHandlers และ HttpModules) และเนื้อหาที่สร้างขึ้น หากคุณมีเพจ ASP.NET ที่สร้างเอาต์พุต (HTML, XML, รูปภาพหรือข้อมูลอื่น ๆ ) และเมื่อคุณเรียกใช้โค้ดนี้กับทุกคำขอ มันจะสร้างเอาต์พุตเดียวกัน แสดงว่าคุณมีเครื่องมือที่สามารถใช้กับ A ทางเลือกที่ดีสำหรับการแคชเอาต์พุตหน้า
โดยเพิ่มบรรทัดต่อไปนี้ที่ด้านบนของหน้า:
<%@ Page OutputCache VaryByParams = "ไม่มี" ระยะเวลา = "60" %>
คุณสามารถสร้างผลลัพธ์สำหรับเพจนี้ได้อย่างมีประสิทธิภาพเพียงครั้งเดียว แล้วนำมาใช้ใหม่หลายครั้งเป็นเวลาสูงสุด 60 วินาที ซึ่งในเวลานั้นเพจจะถูกดำเนินการอีกครั้ง และเอาต์พุตจะถูกเพิ่มลงในแคช ASP.NET อีกครั้ง ลักษณะการทำงานนี้สามารถทำได้โดยใช้ API ที่ตั้งโปรแกรมได้ระดับต่ำบางตัว มีการตั้งค่าที่สามารถกำหนดค่าได้หลายอย่างสำหรับการแคชเอาต์พุต เช่น คุณสมบัติ VaryByParams ที่เพิ่งกล่าวถึง VaryByParams เป็นเพียงการร้องขอ แต่ยังอนุญาตให้คุณระบุพารามิเตอร์ HTTP GET หรือ HTTP POST เพื่อเปลี่ยนรายการแคช ตัวอย่างเช่น เพียงตั้งค่า VaryByParam="Report" เป็นแคชเอาต์พุตสำหรับ default.aspx?Report=1 หรือ default.aspx?Report=2 สามารถระบุพารามิเตอร์เพิ่มเติมได้โดยการระบุรายการที่คั่นด้วยเครื่องหมายอัฒภาค
หลายๆ คนไม่ทราบว่าเมื่อมีการใช้เอาต์พุตแคช หน้า ASP.NET ยังสร้างส่วนหัว HTTP ที่ไหลลงไปยังเซิร์ฟเวอร์แคช เช่น ที่ใช้โดย Microsoft Internet Security and Acceleration Server หรือ Akamai หลังจากตั้งค่าส่วนหัวตารางแคช HTTP แล้ว คุณสามารถแคชเอกสารบนทรัพยากรเครือข่ายเหล่านี้ได้ และสามารถตอบสนองคำขอของไคลเอ็นต์ได้โดยไม่ต้องกลับไปยังเซิร์ฟเวอร์ต้นทาง
ดังนั้น การใช้แคชเอาต์พุตเพจจะไม่ทำให้แอปพลิเคชันของคุณมีประสิทธิภาพมากขึ้น แต่อาจลดภาระบนเซิร์ฟเวอร์ได้เนื่องจากเทคโนโลยีแคชดาวน์สตรีมแคชเอกสาร แน่นอนว่าสิ่งนี้สามารถเป็นเนื้อหาที่ไม่ระบุตัวตนได้เท่านั้น เมื่อเข้าสู่ขั้นตอนปลายน้ำ คุณจะไม่เห็นคำขออีกต่อไป และคุณจะไม่สามารถดำเนินการตรวจสอบสิทธิ์เพื่อป้องกันการเข้าถึงได้อีกต่อไป
เคล็ดลับ 8 — เรียกใช้ IIS 6.0 (แม้จะใช้แคชเคอร์เนลก็ตาม)
หากคุณไม่ได้ใช้ IIS 6.0 (Windows Server 2003) คุณจะพลาดการปรับปรุงประสิทธิภาพที่ยอดเยี่ยมใน Microsoft Web Servers ในเคล็ดลับที่ 7 ฉันพูดถึงการแคชเอาต์พุต ใน IIS 5.0 คำขอจะผ่าน IIS จากนั้นเข้าสู่ ASP.NET เมื่อพูดถึงการแคช HttpModule ใน ASP.NET ได้รับการร้องขอและส่งกลับเนื้อหาของแคช
หากคุณใช้ IIS 6.0 คุณจะพบคุณลักษณะเล็กๆ น้อยๆ ที่เรียกว่าเคอร์เนลแคช ซึ่งไม่จำเป็นต้องเปลี่ยนโค้ดใดๆ ใน ASP.NET เมื่อมีการร้องขอสำหรับการแคชเอาต์พุตโดย ASP.NET แคชเคอร์เนล IIS จะได้รับสำเนาของข้อมูลที่แคชไว้ เมื่อคำขอมาจากไดรเวอร์เครือข่าย ไดรเวอร์ระดับเคอร์เนล (โดยไม่ต้องสลับบริบทไปยังโหมดผู้ใช้) จะได้รับคำขอ จากนั้นล้างข้อมูลแคชไปยังการตอบสนองหากแคชไว้ จากนั้นจึงดำเนินการให้เสร็จสิ้น ซึ่งหมายความว่าเมื่อคุณใช้การแคชโหมดเคอร์เนลกับการแคชเอาต์พุต IIS และ ASP.NET คุณจะเห็นผลลัพธ์ด้านประสิทธิภาพที่น่าทึ่ง ในระหว่างการพัฒนา ASP.NET ใน Visual Studio 2005 ฉันเป็นผู้จัดการฝ่ายพัฒนาที่รับผิดชอบด้านประสิทธิภาพของ ASP.NET นักพัฒนาทำงานเฉพาะด้าน แต่ฉันได้เห็นการรายงานทั้งหมดที่เกิดขึ้นทุกวัน ผลลัพธ์แคชของโหมดเคอร์เนลนั้นน่าสนใจที่สุดเสมอ ลักษณะที่พบบ่อยที่สุดคือเครือข่ายเต็มไปด้วยคำขอ/การตอบกลับ ในขณะที่ IIS ทำงานโดยใช้ CPU เพียงประมาณ 5% เท่านั้น นี่มันน่าตกใจ! แน่นอนว่ามีเหตุผลอื่นในการใช้ IIS 6.0 แต่การแคชโหมดเคอร์เนลเป็นเหตุผลที่ชัดเจนที่สุด
เคล็ดลับ 9 — ใช้การบีบอัด Gzip
แม้ว่าการใช้ gzip จะไม่ใช่เคล็ดลับประสิทธิภาพของเซิร์ฟเวอร์เสมอไป (เนื่องจากคุณอาจเห็นการใช้งาน CPU เพิ่มขึ้น) การใช้การบีบอัด gzip สามารถลดจำนวนไบต์ที่เซิร์ฟเวอร์ส่งได้ ส่งผลให้ความเร็วของเพจเพิ่มขึ้นอย่างเห็นได้ชัดและลดการใช้แบนด์วิธ ขึ้นอยู่กับข้อมูลที่ส่ง สามารถบีบอัดได้แค่ไหน และเบราว์เซอร์ไคลเอนต์รองรับหรือไม่ (IIS จะส่งเฉพาะเนื้อหาที่บีบอัด gzip ไปยังไคลเอนต์ที่รองรับการบีบอัด gzip เช่น Internet Explorer 6.0 และ Firefox) เซิร์ฟเวอร์ของคุณสามารถให้บริการได้มากขึ้น คำขอ ในความเป็นจริง เกือบทุกครั้งที่คุณลดปริมาณข้อมูลที่ส่งคืน คุณจะเพิ่มจำนวนคำขอต่อวินาที
การบีบอัด Gzip มีอยู่ใน IIS 6.0 และประสิทธิภาพดีกว่าการบีบอัด gzip ที่ใช้ใน IIS 5.0 มาก ซึ่งเป็นข่าวดี ขออภัย เมื่อพยายามเปิดการบีบอัด gzip ใน IIS 6.0 คุณอาจไม่พบการตั้งค่าในกล่องโต้ตอบคุณสมบัติของ IIS ทีมงาน IIS ได้สร้างฟังก์ชัน gzip ที่ยอดเยี่ยมไว้ในเซิร์ฟเวอร์ แต่ลืมใส่ UI การดูแลระบบเพื่อเปิดใช้งาน หากต้องการเปิดใช้งานการบีบอัด gzip คุณต้องเจาะลึกการตั้งค่าการกำหนดค่า XML ของ IIS 6.0 (เพื่อที่คุณจะได้ไม่ใจอ่อน) โดยบังเอิญ เครดิตไปที่ Scott Forsyth จาก OrcsWeb ที่ช่วยฉันแจ้งปัญหานี้กับเซิร์ฟเวอร์ www.asp.net ที่โฮสต์บน OrcsWeb
บทความนี้จะไม่อธิบายขั้นตอนต่างๆ โปรดอ่านบทความของ Brad Wilson ที่ IIS6 Compression นอกจากนี้ยังมีบทความฐานความรู้เกี่ยวกับการเปิดใช้งานการบีบอัดสำหรับ ASPX ที่เปิดใช้งานการบีบอัด ASPX ใน IIS อย่างไรก็ตาม คุณควรทราบว่า เนื่องจากรายละเอียดการใช้งานบางอย่าง การบีบอัดแบบไดนามิกและการแคชเคอร์เนลจึงไม่สามารถอยู่พร้อมกันใน IIS 6.0
เคล็ดลับ 10 — สถานะมุมมองการควบคุมเซิร์ฟเวอร์
View state เป็นชื่อที่น่าสนใจสำหรับ ASP.NET ที่เก็บข้อมูลสถานะบางส่วนไว้ในฟิลด์เอาต์พุตที่ซ่อนอยู่ของเพจที่สร้างขึ้น เมื่อเพจถูกส่งกลับไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์สามารถแยกวิเคราะห์ ตรวจสอบ และใช้ข้อมูลสถานะมุมมองนี้กลับไปยังโครงสร้างการควบคุมของเพจ สถานะการดูเป็นคุณลักษณะที่มีประสิทธิภาพมากเนื่องจากช่วยให้สามารถคงสถานะไว้กับไคลเอ็นต์ได้ และไม่ต้องใช้คุกกี้หรือหน่วยความจำเซิร์ฟเวอร์ในการบันทึกสถานะนี้ ตัวควบคุมเซิร์ฟเวอร์ ASP.NET จำนวนมากใช้สถานะมุมมองเพื่อคงการตั้งค่าที่สร้างขึ้นระหว่างการโต้ตอบกับองค์ประกอบของเพจ เช่น การบันทึกเพจปัจจุบันที่จะแสดงเมื่อมีการแบ่งหน้าข้อมูล
อย่างไรก็ตาม การใช้ view state ก็มีข้อเสียอยู่บ้างเช่นกัน ขั้นแรก เพิ่มภาระโดยรวมบนเพจเมื่อมีการแสดงหรือร้องขอ ค่าใช้จ่ายเพิ่มเติมยังเกิดขึ้นเมื่อซีเรียลไลซ์หรือดีซีเรียลไลซ์ข้อมูลสถานะมุมมองที่ส่งกลับไปยังเซิร์ฟเวอร์ ในที่สุด สถานะการดูจะเพิ่มการจัดสรรหน่วยความจำบนเซิร์ฟเวอร์
การควบคุมเซิร์ฟเวอร์หลายตัวมีแนวโน้มที่จะใช้สถานะมุมมองมากเกินไปแม้ว่าจะไม่จำเป็นก็ตาม ที่โดดเด่นที่สุดคือ DataGrid ลักษณะการทำงานเริ่มต้นของคุณสมบัติ ViewState เปิดอยู่ แต่คุณสามารถปิดได้ที่ระดับการควบคุมหรือหน้าหากไม่ต้องการ ภายในตัวควบคุม เพียงตั้งค่าคุณสมบัติ EnableViewState เป็นเท็จ หรือตั้งค่าส่วนกลางบนเพจโดยใช้การตั้งค่าต่อไปนี้:
<%@ หน้า EnableViewState = "false" %>
หากคุณไม่โพสต์กลับเพจ หรือสร้างการควบคุมบนเพจใหม่ทุกครั้งในทุกคำขอ คุณควรปิดการใช้งานสถานะการดูที่ระดับเพจ
สรุป
ฉันได้ให้คำแนะนำที่เป็นประโยชน์แก่คุณเมื่อเขียนแอปพลิเคชัน ASP.NET ประสิทธิภาพสูง ดังที่ได้กล่าวไปแล้วในบทความนี้ นี่เป็นคำแนะนำเบื้องต้นและไม่ใช่คำสุดท้ายเกี่ยวกับประสิทธิภาพของ ASP.NET (สำหรับข้อมูลเกี่ยวกับการปรับปรุงประสิทธิภาพของแอปพลิเคชัน ASP.NET โปรดดูการปรับปรุงประสิทธิภาพ ASP.NET) วิธีที่ดีที่สุดในการแก้ปัญหาประสิทธิภาพเฉพาะสามารถพบได้จากประสบการณ์ของคุณเท่านั้น อย่างไรก็ตาม เคล็ดลับเหล่านี้ควรให้คำแนะนำที่ดีแก่คุณในการเดินทางของคุณ ในการพัฒนาซอฟต์แวร์ มีเพียงไม่กี่อย่างเท่านั้นที่ทุกแอปพลิเคชันมีเอกลักษณ์เฉพาะตัว
ดูแถบด้านข้าง "ความเชื่อผิดๆ เกี่ยวกับประสิทธิภาพทั่วไป"
Rob Howard เป็นผู้ก่อตั้ง Telligent Systems ซึ่งเชี่ยวชาญด้านแอปพลิเคชันเว็บประสิทธิภาพสูง การจัดการฐานความรู้ และระบบการทำงานร่วมกัน ก่อนหน้านี้ Rob เคยร่วมงานกับ Microsoft โดยเขาได้ช่วยออกแบบโครงสร้างพื้นฐานสำหรับ ASP.NET 1.0, 1.1 และ 2.0 หากต้องการติดต่อ Rob โปรดไปที่ [email protected]
ลิงค์ต้นฉบับ: http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx