แล้วมีจำนวนมากที่ดีแนวทางในคำตอบให้ ( ที่นี่ , ที่นี่และที่นี่ ) หากความเร็วคือสิ่งที่คุณมองหาเป็นหลักคุณควรพิจารณาทำงานผ่าน C API ของ Lua ซึ่งเร็วกว่ารหัส Lua ดิบหลายเท่า เมื่อทำงานกับชิ้นส่วนที่โหลดไว้ล่วงหน้า (เช่นฟังก์ชั่นโหลด ) ความแตกต่างนั้นไม่มาก แต่ก็ยังมีอยู่มาก
ในส่วนของ โซลูชัน Lua ที่บริสุทธิ์ขอฉันแบ่งปันเกณฑ์มาตรฐานเล็ก ๆ ที่ฉันได้สร้างขึ้น ครอบคลุมทุกคำตอบสำหรับวันนี้และเพิ่มการเพิ่มประสิทธิภาพเล็กน้อย อย่างไรก็ตามสิ่งพื้นฐานที่ควรพิจารณาคือ:
คุณจะต้องวนซ้ำอักขระในสตริงกี่ครั้ง?
- หากคำตอบคือ "ครั้งเดียว" คุณควรค้นหาส่วนแรกของแบนเนอร์ ("ความเร็วดิบ")
- มิฉะนั้นส่วนที่สองจะให้การประมาณที่แม่นยำยิ่งขึ้นเนื่องจากจะแยกวิเคราะห์สตริงลงในตารางซึ่งเร็วกว่ามากในการทำซ้ำ คุณควรพิจารณาเขียนฟังก์ชันง่ายๆสำหรับสิ่งนี้เช่นที่ @Jarriz แนะนำ
นี่คือรหัสเต็ม:
local str = "Hello World!"
local attempts = 5000000
local reuses = 10
local x, c, elapsed, tbl
local stringbyte, stringchar, stringsub, stringgsub, stringgmatch = string.byte, string.char, string.sub, string.gsub, string.gmatch
print("-----------------------")
print("Raw speed:")
print("-----------------------")
x = os.clock()
for j = 1, attempts do
for i = 1, #str do
c = stringsub(str, i)
end
end
elapsed = os.clock() - x
print(string.format("V1: elapsed time: %.3f", elapsed))
x = os.clock()
for j = 1, attempts do
for c in stringgmatch(str, ".") do end
end
elapsed = os.clock() - x
print(string.format("V2: elapsed time: %.3f", elapsed))
x = os.clock()
for j = 1, attempts do
stringgsub(str, ".", function(c) end)
end
elapsed = os.clock() - x
print(string.format("V3: elapsed time: %.3f", elapsed))
local str2table = function(str)
local ret = {}
for i = 1, #str do
ret[i] = stringsub(str, i)
end
return ret
end
x = os.clock()
for j = 1, attempts do
tbl = str2table(str)
for i = 1, #tbl do
c = tbl[i]
end
end
elapsed = os.clock() - x
print(string.format("V4: elapsed time: %.3f", elapsed))
x = os.clock()
for j = 1, attempts do
tbl = {stringbyte(str, 1, #str)}
for i = 1, #tbl do
c = tbl[i]
end
end
elapsed = os.clock() - x
print(string.format("V5: elapsed time: %.3f", elapsed))
x = os.clock()
for j = 1, attempts do
tbl = {stringbyte(str, 1, #str)}
for i = 1, #tbl do
c = stringchar(tbl[i])
end
end
elapsed = os.clock() - x
print(string.format("V5b: elapsed time: %.3f", elapsed))
print("-----------------------")
print("Creating cache table ("..reuses.." reuses):")
print("-----------------------")
x = os.clock()
for k = 1, attempts do
tbl = {}
for i = 1, #str do
tbl[i] = stringsub(str, i)
end
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V1: elapsed time: %.3f", elapsed))
x = os.clock()
for k = 1, attempts do
tbl = {}
local tblc = 1
for c in stringgmatch(str, ".") do
tbl[tblc] = c
tblc = tblc + 1
end
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V2: elapsed time: %.3f", elapsed))
x = os.clock()
for k = 1, attempts do
tbl = {}
local tblc = 1
stringgsub(str, ".", function(c)
tbl[tblc] = c
tblc = tblc + 1
end)
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V3: elapsed time: %.3f", elapsed))
x = os.clock()
for k = 1, attempts do
tbl = str2table(str)
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V4: elapsed time: %.3f", elapsed))
x = os.clock()
for k = 1, attempts do
tbl = {stringbyte(str,1,#str)}
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V5: elapsed time: %.3f", elapsed))
x = os.clock()
for k = 1, attempts do
tbl = {stringbyte(str, 1, #str)}
for i = 1, #tbl do
tbl[i] = stringchar(tbl[i])
end
for j = 1, reuses do
for i = 1, #tbl do
c = tbl[i]
end
end
end
elapsed = os.clock() - x
print(string.format("V5b: elapsed time: %.3f", elapsed))
ตัวอย่างผลลัพธ์ (Lua 5.3.4, Windows) :
Raw speed:
V1: elapsed time: 3.713
V2: elapsed time: 5.089
V3: elapsed time: 5.222
V4: elapsed time: 4.066
V5: elapsed time: 2.627
V5b: elapsed time: 3.627
Creating cache table (10 reuses):
V1: elapsed time: 20.381
V2: elapsed time: 23.913
V3: elapsed time: 25.221
V4: elapsed time: 20.551
V5: elapsed time: 13.473
V5b: elapsed time: 18.046
ผลลัพธ์:
ในกรณีของฉันstring.byte
และstring.sub
เร็วที่สุดในแง่ของความเร็วดิบ เมื่อใช้ตารางแคชและนำกลับมาใช้ใหม่ 10 ครั้งต่อลูปไฟล์string.byte
เวอร์ชันนี้เร็วที่สุดแม้ว่าจะแปลงชาร์โค้ดกลับไปเป็นตัวอักษร (ซึ่งไม่จำเป็นเสมอไปและขึ้นอยู่กับการใช้งาน)
อย่างที่คุณสังเกตเห็นฉันได้ตั้งสมมติฐานตามเกณฑ์มาตรฐานก่อนหน้าของฉันและนำไปใช้กับโค้ด:
- ฟังก์ชันไลบรารีควรแปลเป็นภาษาท้องถิ่นเสมอหากใช้ภายในลูปเพราะเร็วกว่ามาก
- การใส่องค์ประกอบใหม่ลงในตารางหลัวรวดเร็วยิ่งขึ้นโดยใช้
tbl[idx] = value
กว่าtable.insert(tbl, value)
กว่า
- การวนซ้ำโดยใช้ตาราง
for i = 1, #tbl
นั้นเร็วกว่าเล็กน้อยfor k, v in pairs(tbl)
ซ้ำเล็กน้อย
- มักจะชอบเวอร์ชันที่มีการเรียกใช้ฟังก์ชันน้อยกว่าเนื่องจากการเรียกใช้จะเพิ่มเวลาดำเนินการเล็กน้อย
หวังว่าจะช่วยได้