การสร้างโค้ดเดิม

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

ด้วยการสนับสนุน Luau สําหรับการสร้างโค้ดเดิม, สคริปต์ด้านเซิร์ฟเวอร์ในประสบการณ์ของคุณสามารถรวบรวมโดยตรงเป็นคําแนะนําในการรันโค้ดของเครื่องที่ซีพียูดําเนินการได้ แทนที่จะเป็นบายต์โค้ดปกติที่ Luau VM ดําเนินการคุณสมบัตินี้สามารถใช้เพื่อปรับปรุงความเร็วในการดำเนินการสำหรับบางสคริปต์บนเซิร์ฟเวอร์โดยเฉพาะอย่างยิ่งสคริปต์ที่มีการคำนวณทางเลขมากมายโดยไม่ต้องใช้ Luau หรือ Roblox API จํานวนมากเกินไป

เปิดใช้งานการสร้างโค้ดเดิม

เพื่อเปิดใช้งานการสร้างโค้ดเดิมสําหรับ Script เพิ่มความคิดเห็น --!native ที่ด้านบน:¹


--!โค้ดเดิม
print("Hello from native code!")

สิ่งนี้ช่วยให้การสร้างโค้ดเดิมสำหรับฟังก์ชันทั้งหมดในสคริปต์และขอบเขตระดับสูงถ้าถือว่ามีประโยชน์ไม่จำเป็นต้องมีการเปลี่ยนแปลงเพิ่มเติม; พฤติกรรมของการดําเนินสคริปต์โดยตรงคือเหมือนเดิมก่อนและเฉพาะประสิทธิภาพเท่านั้นที่แตกต่างกันคุณลักษณะทั้งหมดของภาษา Luau และ API Roblox ทั้งหมดยังคงได้รับการสนับสนุน

หรือคุณสามารถเปิดใช้งานการสร้างโค้ดเดิมสำหรับฟังก์ชันแต่ละรายการโดยการเพิ่มคุณสมบัติ @native:


@native
local function f(x)
return (x + 1)
end
1 ในอนาคตบางสคริปต์อาจเริ่มทำงานโดยอัตโนมัติโดยอัตโนมัติหากกำหนดให้เป็นที่ทำกำไรได้ แต่ต้องใส่ความคิดเห็นด้วยมือ --!native ในปัจจุบัน

แนวทางที่ดีที่สุด

เคล็ดลับต่อไปนี้จะช่วยให้คุณได้รับประโยชน์สูงสุดจากการสร้างโค้ดเดิม:

  • ควรเปิดใช้งานคุณลักษณะนี้ภายในสคริปที่ดำเนินการคำนวณจํานวนมากโดยตรงภายใน Luauหากคุณมีการดำเนินการทางคณิตศาสตร์จํานวนมากบนตารางและโดยเฉพาะอย่างยิ่งประเภท buffer สคริปต์อาจเป็นผู้สมัครที่ดี

  • เฉพาะฟังก์ชันของสคริปต์ เท่านั้น ที่รวบรวมโดยตรงโค้ดในส่วนนอกสูงสุด ขอบเขต มักจะถูกดำเนินการเพียงครั้งเดียวและไม่ได้รับประโยชน์มากเท่าที่ฟังก์ชันที่เรียกหลายครั้งจะได้รับ โดยเฉพาะอย่างยิ่งผู้ที่เรียกทุกเฟรม

  • ขอแนะนำให้คุณวัดเวลาที่สคริปต์หรือฟังก์ชันใช้กับและโดยไม่มีการแยกไคลเอนต์เพื่อตัดสินว่าเมื่อใดที่เหมาะสมที่สุดที่จะใช้มันเครื่องมือ โปรไฟล์สคริปต์ สามารถวัดประสิทธิภาพของฟังก์ชันเพื่อตัดสินใจได้อย่างมีข้อมูล

  • อาจจะน่าล่อลวงที่จะวางความคิดเห็น --!native ใน ทุก สคริปต์เพียงในกรณีที่บางส่วนของพวกเขาจะดำเนินการได้เร็วขึ้น แต่การสร้างโค้ดเดิมมีข้อด้อยบางอย่าง:

    • ต้องใช้เวลาในการรวบรวมโค้ดซึ่งอาจเพิ่มเวลาเปิดระบบของเซิร์ฟเวอร์
    • หน่วยความจําเสริมถูกใช้เพื่อเก็บโค้ดที่สร้างขึ้นโดยตรง
    • มีขีดจํากัดในจํานวนเงินที่อนุญาตทั้งหมดของโค้ดที่รวบรวมโดยตรงในประสบการณ์

ปัญหาเหล่านี้สามารถแก้ไขได้โดยการใช้คุณลักษณะ @native อย่างชาญฉลาด

รหัสที่ต้องหลีกเลี่ยง

ในขณะที่คุณสมบัติทั้งหมดจะทำงานเหมือนกันกับหรือไม่มีการเปิดใช้งานการสร้างโค้ดเดิม บางส่วนจะไม่ทำงานโดยตรงและอาจทําให้เกิดการเพิ่มประสิทธิภาพหรือการย้อนกลับไปสู่การดําเนินการตามตัวอักษรซึ่งรวมถึง:

  • การใช้การโทร getfenv() / setfenv() ที่ล้าสมัย
  • การใช้ฟังก์ชันที่บรรจุไว้ใน Luau หลายอย่างเช่น math.asin() ด้วยอาร์กิวเมนต์ที่ไม่ใช่ตัวเลข
  • ส่งพารามิเตอร์ที่พิมพ์ไม่ถูกต้องไปยังฟังก์ชันที่พิมพ์ไว้ ตัวอย่างเช่น เรียก foo(true) เมื่อ foo ถูกประกาศว่าเป็น function foo(arg: string)อย่าลืมใช้การแสดงคําอธิบายประเภทที่ถูกต้องเสมอ

เมื่อใช้ โปรไฟล์สคริปต์ คุณสามารถเปรียบเทียบเวลาที่ใช้โดยเวอร์ชันปกติของฟังก์ชันกับเวอร์ชันที่สะสมโดยธรรมชาติหากฟังก์ชันภายในสคริปต์ --!native ถูกบอกด้วย @native ไม่ปรากฏว่ากําลังดําเนินการโดยธรรมชาติ อาจมีปัจจัยหนึ่งหรือมากกว่าจากรายการด้านบนที่กําลังกระตุ้นการเพิ่มประสิทธิภาพ

ใช้การบอกประเภท

ความพยายามในการสร้างโค้ดเดิมจะพยายามคาดเดาประเภทที่น่าจะเป็นไปได้สำหรับตัวแปรที่กำหนดเพื่อเพิ่มประสิทธิภาพเส้นทางโค้ดตัวอย่างเช่น คาดว่า a + b จะดำเนินการบนตัวเลข หรือว่าตารางจะเข้าถึงได้ใน t.Xอย่างไรก็ตาม การโอเวอร์โหลดตัวประกอบจะทำให้ตาราง a และ b เป็นตารางหรือประเภท Vector3 หรือ t อาจเป็นประเภทข้อมูล Roblox

พิมพ์การคาดเดาผิดพลาดอาจกระตุ้นการตรวจสอบที่ไม่จำเป็น ส่งผลให้การดำเนินการโค้ดช้าลง

เพื่อแก้ปัญหาทั่วไปบางอย่าง Luau ประเภทการแสดงความเห็นบนอาร์กิวเมนต์ฟังก์ชันจะตรวจสอบ แต่เป็นที่แนะนำเป็นพิเศษที่จะแสดงความเห็น Vector3 อาร์กิวเมนต์:


--!โค้ดเดิม
-- สมมติว่า "v" เป็นตาราง; ฟังก์ชันทำงานช้าลงเนื่องจากการตรวจสอบตาราง
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- “v” ถูกประกาศว่าเป็น Vector3; รหัสที่กำหนดเองสำหรับเวกเตอร์ถูกสร้างขึ้น
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

เครื่องมือสตูดิโอ

เครื่องมือสตูดิโอต่อไปนี้สนับสนุนสำหรับ --!native สคริปต์และ @native ฟังก์ชัน

การแก้ไขข้อผิดพลาด

การแก้ไขข้อผิดพลาดทั่วไปของสคริปต์ได้รับการสนับสนุน แต่มุมมองสำหรับท้องถิ่น/มูลค่าสูงสุดอาจไม่สมบูรณ์และขาดแปรจาก กองเรียกเรียก เฟรมที่ดำเนินการโดยตรง

โปรดทราบว่าเมื่อแก้ไขข้อผิดพลาดโค้ดที่เลือกสําหรับการแสดงผลในรูปแบบเดิม การวาง จุดหยุดชะงัก จะปิดการดําเนินการแบบเดิมสําหรับฟังก์ชันเหล่านั้น

โปรไฟล์สคริปต์

ใน โปรไฟล์สคริปต์ ฟังก์ชันที่ดำเนินการโดยตรงแสดงผล <native> ข้างๆ พวกเขา:

Example of native functions flagged in the Script Profiler

หากฟังก์ชันที่ถูกทําเครื่องหมาย @native หรืออยู่ภายในสคริปต์ --!native ไม่แสดงคําอธิบาย <native> นั่นหมายความว่าฟังก์ชันนั้นอาจไม่ได้รับการดําเนินการโดยตรงเนื่องจากการวางจุดหยุด การใช้ รหัสที่หลีกเลี่ยงได้ หรือคําอธิบายประเภท ไม่ตรงกัน

กอง Luau

ในโปรไฟล์เลอร์ Luau heap หน่วยความจําที่ใช้โดยฟังก์ชันเดิมแสดงเป็นองค์ประกอบ [native] ในกราฟ

Example of native memory usage flagged in the Luau Heap profiler

การวิเคราะห์ขนาด

สคริปต์ที่รวบรวมเองทั้งหมดใช้หน่วยความจําทุกครั้งเมื่อขนาดของโค้ดที่รวบรวมถึงขีดจํากัดที่กําหนดไว้ล่วงหน้าแล้ว การแยกรวบรวมแบบเดิมจะหยุดลงและโค้ดที่เหลือจะถูกดําเนินการโดยไม่ต้องแปลงสิ่งนี้ทำให้เป็นสิ่งสำคัญที่ต้องเลือกสคริปต์อย่างระมัดระวังสำหรับการรวบรวมแบบเดิม

เพื่อตรวจสอบขนาดโค้ดเดิมของฟังก์ชันและสคริปต์แต่ละอัน:

  1. ตรวจสอบให้แน่ใจว่าคุณอยู่ในมุมมอง เซิร์ฟเวอร์ ผ่านปุ่ม สลับไคลเอนต์/เซิร์ฟเวอร์
  2. เรียก debug.dumpcodesize() จาก แถบคําสั่ง .

ในหน้าต่าง การออก คุณจะเห็นจํานวนสคริปต์และฟังก์ชันทั้งหมดที่ได้รับการแปลงเป็นรูปแบบเดิมจนถึงจุดเรียกใช้ หน่วยความจําที่ใช้โดยรหัสเดิมของพวกเขา และขีดจํากัดขนาดรหัสเดิมหลังจากสรุปแล้ว คุณจะเห็นตารางสำหรับทุกสคริปต์ที่รวบรวมโดยตรงในลำดับขนาดโค้ดลดลง

Example of native code size displayed in the Output window.

สำหรับแต่ละสคริปต์ผลลัพธ์จะแสดงจํานวนฟังก์ชันที่รวบรวมและการใช้หน่วยความจํารหัสเดิมที่ใช้แต่ละฟังก์ชันจะถูกระบุในลำดับลดลงตามขนาดโค้ดเดิมด้วยฟังก์ชันที่ไม่ระบุชื่อแสดงเป็น [anonymous] และสคริปต์ทั้งหมดแสดงเป็น [top level]ในคอลัมน์สุดท้าย เปอร์เซ็นต์จะคำนวณโดยคำนึงถึงขีดจํากัดขนาดโค้ดเดิมโปรดทราบว่าขนาดโค้ดเดิมของฟังก์ชันรายงานอย่างถูกต้อง แต่การใช้หน่วยความจําสําหรับสคริปต์ถูกรอบขึ้นไปที่ขนาดหน้าที่ใกล้เคียงที่สุด

ข้อจํากัดและการแก้ปัญหา

การรวบรวมโค้ดเป็นคําแนะนําสําหรับ CPU เฉพาะต้องใช้หน่วยความจําเพิ่มเติมนอกจากนี้การปรับแต่งสําหรับฟังก์ชันที่ซับซ้อนอาจใช้เวลานานเกินไปในการดําเนินการการโจมตีขีดจํากัดภายในจะรายงานข้อผิดพลาดในหน้าต่าง การออก ของ Studio รวมถึง:

ฟังก์ชัน 'f' ที่บรรทัดที่ 20 เกินขีดจํากัดคําสั่งบล็อกโค้ดเดียว

ข้อผิดพลาดนี้หมายความว่าบล็อกเดียวของโค้ดภายในฟังก์ชันใช้มากกว่า 64K คําสั่งสามารถหลีกเลี่ยงได้โดยการเรียบเรียงฟังก์ชันให้เรียบง่ายหรือแยกออกเป็นฟังก์ชันขนาดเล็กแต่ละรายการ

ฟังก์ชัน 'f' ที่บรรทัดที่ 20 เกินขีดจํากัดรหัสฟังก์ชัน

รหัส32Kบล็อกภายในของโค้ดไม่สอดคล้องกับบล็อกการไหลของควบคุมในสคริปต์อย่างแน่นอน แต่ข้อผิดพลาดนี้สามารถหลีกเลี่ยงได้โดยการเรียบเรียงการไหลของควบคุมในฟังก์ชันให้เรียบง่ายหรือแยกออกเป็นฟังก์ชันขนาดเล็ก

ฟังก์ชัน 'f' ที่บรรทัด 200 เกินขีดจํากัดคําสั่งโมดูลทั้งหมด

ข้อผิดพลาดนี้หมายความว่าในทั้งหมดฟังก์ชันได้ถึงขีดจํากัด 1 ล้านคําสั่งสําหรับทั้งบทความในบางกรณีฟังก์ชันที่รายงานเองอาจมีคําแนะนําจํานวนมาก หรือขีดจํากัดอาจถูกบรรลุโดยฟังก์ชันก่อนหน้าในสคริปต์เพื่อหลีกเลี่ยงปัญหานี้ จึงแนะนำให้ย้ายฟังก์ชันขนาดใหญ่พิเศษไปยังสคริปต์ที่ไม่ใช่ภาษาเดิมหรือใช้ @native กับฟังก์ชันอื่นๆคุณยังสามารถลองทำเครื่องหมายสคริปต์ที่แยกออกจากกันด้วย --!native แต่ 1 ล้านคำสั่งใช้ความทรงจำจํานวนมากและคุณอาจเกินขีดจํากัดความทรงจำ

*ฟังก์ชัน 'f' ที่บรรทัดที่ 20 พบความล้มเหลวในการลดลงภายใน *(หรือ) ความผิดพลาดภายใน: การสร้างโค้ดเดิมพันล้มเหลว (การลดลงของการประกอบ)

บางครั้งฟังก์ชันมีบิตโค้ดที่ซับซ้อนที่คอมไพเลอร์โค้ดเดิมไม่สามารถจัดการได้ในปัจจุบันเพื่อหลีกเลี่ยงข้อผิดพลาดนี้ ตรวจสอบการแสดงออกที่ซับซ้อนในรหัสและแยกออกหรือเรียบเรียงให้เรียบง่าย แต่ยังพิจารณาเปิดรายงานข้อบกพร่องด้วยตัวอย่างของรหัสที่ล้มเหลวด้วยเหตุผลนี้

ถึงขีดจํากัดการจัดสรรหน่วยความจําสําหรับการสร้างโค้ดเดิมแล้ว

ข้อผิดพลาดนี้หมายความว่าขีดจํากัดความทรงจําโดยรวมสําหรับข้อมูลโค้ดเดิมถูกบรรลุแล้วเพื่อหลีกเลี่ยงสิ่งนี้ ลองลบ --!native จากสคริปต์ที่ใช้ทรัพยากรหน่วยความจำมากขึ้น เพื่อให้สคริปต์ขนาดเล็กกว่าสามารถพอดีภายใต้ขีดจํากัดได้อีกทางหนึ่งให้ย้ายฟังก์ชันขนาดใหญ่หรือเรียกไม่บ่อยไปยังโมดูลที่ไม่ใช่ภาษาเดิม