หากมีสตริงเดียวกันอย่างน้อยสองอินสแตนซ์ในสคริปต์ของฉันฉันควรใช้สัญลักษณ์แทนหรือไม่
หากมีสตริงเดียวกันอย่างน้อยสองอินสแตนซ์ในสคริปต์ของฉันฉันควรใช้สัญลักษณ์แทนหรือไม่
คำตอบ:
หลักการง่ายๆคือการใช้สัญลักษณ์ทุกครั้งที่คุณต้องการตัวระบุภายใน สำหรับ Ruby <2.2 ใช้เฉพาะสัญลักษณ์เมื่อไม่ได้สร้างแบบไดนามิกเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ
เหตุผลเดียวที่ไม่ใช้สำหรับตัวระบุที่สร้างขึ้นแบบไดนามิกเป็นเพราะปัญหาเกี่ยวกับหน่วยความจำ
คำถามนี้เป็นคำถามที่พบบ่อยมากเนื่องจากภาษาโปรแกรมจำนวนมากไม่มีสัญลักษณ์มีเพียงสตริงดังนั้นจึงใช้สตริงเป็นตัวระบุในโค้ดของคุณด้วย คุณควรกังวลเกี่ยวกับความหมายของสัญลักษณ์ไม่ใช่เฉพาะเมื่อคุณควรใช้สัญลักษณ์เท่านั้น สัญลักษณ์หมายถึงตัวระบุ หากคุณปฏิบัติตามปรัชญานี้โอกาสที่คุณจะทำสิ่งที่ถูกต้อง
มีความแตกต่างหลายประการระหว่างการใช้สัญลักษณ์และสตริง สิ่งที่สำคัญที่สุดเกี่ยวกับสัญลักษณ์คือไม่เปลี่ยนรูปไม่เปลี่ยนรูปนั่นหมายความว่าค่าของพวกเขาจะไม่มีทางเปลี่ยนแปลง ด้วยเหตุนี้สัญลักษณ์จึงสร้างอินสแตนซ์ได้เร็วกว่าสตริงและการดำเนินการบางอย่างเช่นการเปรียบเทียบสองสัญลักษณ์ก็เร็วกว่าเช่นกัน
ความจริงที่ว่าสัญลักษณ์ไม่เปลี่ยนรูปทำให้ Ruby สามารถใช้วัตถุเดียวกันทุกครั้งที่คุณอ้างอิงสัญลักษณ์ซึ่งช่วยประหยัดหน่วยความจำ ดังนั้นทุกครั้งที่ล่ามอ่าน:my_key
มันสามารถใช้มันจากหน่วยความจำแทนที่จะสร้างอินสแตนซ์อีกครั้ง ซึ่งมีค่าใช้จ่ายน้อยกว่าการเริ่มต้นสตริงใหม่ทุกครั้ง
คุณสามารถรับรายการสัญลักษณ์ทั้งหมดที่สร้างอินสแตนซ์ด้วยคำสั่งแล้วSymbol.all_symbols
:
symbols_count = Symbol.all_symbols.count # all_symbols is an array with all
# instantiated symbols.
a = :one
puts a.object_id
# prints 167778
a = :two
puts a.object_id
# prints 167858
a = :one
puts a.object_id
# prints 167778 again - the same object_id from the first time!
puts Symbol.all_symbols.count - symbols_count
# prints 2, the two objects we created.
สำหรับ Ruby เวอร์ชันก่อน 2.2 เมื่อสร้างสัญลักษณ์แล้วหน่วยความจำนี้จะไม่เป็นอิสระอีกต่อไป วิธีเดียวที่จะทำให้หน่วยความจำว่างคือการรีสตาร์ทแอปพลิเคชัน ดังนั้นสัญลักษณ์จึงเป็นสาเหตุสำคัญของการรั่วไหลของหน่วยความจำเมื่อใช้ไม่ถูกต้อง วิธีที่ง่ายที่สุดในการสร้างการรั่วไหลของหน่วยความจำคือการใช้วิธีการto_sym
ป้อนข้อมูลของผู้ใช้เนื่องจากข้อมูลนี้จะเปลี่ยนแปลงตลอดเวลาส่วนใหม่ของหน่วยความจำจะถูกใช้ตลอดไปในอินสแตนซ์ซอฟต์แวร์ Ruby 2.2 เปิดตัวสัญลักษณ์ตัวเก็บขยะซึ่งปลดปล่อยสัญลักษณ์ที่สร้างขึ้นแบบไดนามิกดังนั้นการรั่วไหลของหน่วยความจำที่เกิดจากการสร้างสัญลักษณ์แบบไดนามิกจึงไม่น่ากังวลอีกต่อไป
ตอบคำถามของคุณ:
เป็นความจริงหรือไม่ที่ฉันต้องใช้สัญลักษณ์แทนสตริงหากมีอย่างน้อยสองสตริงเดียวกันในแอปพลิเคชันหรือสคริปต์ของฉัน
หากสิ่งที่คุณกำลังมองหาคือตัวระบุที่จะใช้ภายในรหัสของคุณคุณควรใช้สัญลักษณ์ หากคุณกำลังพิมพ์เอาต์พุตคุณควรใช้สตริงแม้ว่าจะปรากฏมากกว่าหนึ่งครั้งก็ตามแม้กระทั่งการจัดสรรอ็อบเจ็กต์สองชิ้นในหน่วยความจำ
นี่คือเหตุผล:
@AlanDert: ถ้าฉันใช้หลาย ๆ ครั้งเช่น% input {type:: checkbox} ในโค้ด haml ฉันควรใช้อะไรเป็นช่องทำเครื่องหมาย
ฉัน: ใช่
@AlanDert: แต่ในการพิมพ์สัญลักษณ์บนหน้า html ควรแปลงเป็นสตริงหรือไม่? อะไรคือจุดที่ใช้มัน?
อินพุตคืออะไร? ตัวระบุประเภทอินพุตที่คุณต้องการใช้หรือสิ่งที่คุณต้องการแสดงต่อผู้ใช้?
เป็นความจริงที่ว่าจะกลายเป็นโค้ด HTML ในบางจุด แต่ในขณะที่คุณเขียนโค้ดบรรทัดนั้นหมายถึงการเป็นตัวระบุซึ่งจะระบุว่าคุณต้องการช่องป้อนข้อมูลประเภทใด ดังนั้นจึงใช้ซ้ำแล้วซ้ำอีกในรหัสของคุณและมี "สตริง" ของอักขระเป็นตัวระบุเสมอและจะไม่ทำให้หน่วยความจำรั่วไหล
ที่กล่าวว่าทำไมเราไม่ประเมินข้อมูลเพื่อดูว่าสตริงเร็วขึ้นหรือไม่?
นี่เป็นเกณฑ์มาตรฐานง่ายๆที่ฉันสร้างขึ้นสำหรับสิ่งนี้:
require 'benchmark'
require 'haml'
str = Benchmark.measure do
10_000.times do
Haml::Engine.new('%input{type: "checkbox"}').render
end
end.total
sym = Benchmark.measure do
10_000.times do
Haml::Engine.new('%input{type: :checkbox}').render
end
end.total
puts "String: " + str.to_s
puts "Symbol: " + sym.to_s
สามเอาท์พุท:
# first time
String: 5.14
Symbol: 5.07
#second
String: 5.29
Symbol: 5.050000000000001
#third
String: 4.7700000000000005
Symbol: 4.68
ดังนั้นการใช้ smbol จะเร็วกว่าการใช้สตริงเล็กน้อย ทำไมถึงเป็นเช่นนั้น? ขึ้นอยู่กับวิธีการใช้งาน HAML ฉันจะต้องแฮ็กโค้ด HAML เล็กน้อยเพื่อดู แต่ถ้าคุณยังคงใช้สัญลักษณ์ในแนวคิดของตัวระบุแอปพลิเคชันของคุณจะเร็วขึ้นและเชื่อถือได้ เมื่อเกิดคำถามให้เปรียบเทียบและรับคำตอบของคุณ
พูดง่ายๆคือสัญลักษณ์คือชื่อซึ่งประกอบด้วยอักขระ แต่ไม่เปลี่ยนรูป ในทางตรงกันข้ามสตริงเป็นคอนเทนเนอร์ที่สั่งซื้อสำหรับอักขระซึ่งเนื้อหาได้รับอนุญาตให้เปลี่ยนแปลง
นี่คือเกณฑ์มาตรฐานที่ดีของสตริงและสัญลักษณ์ที่ฉันพบใน codecademy:
require 'benchmark'
string_AZ = Hash[("a".."z").to_a.zip((1..26).to_a)]
symbol_AZ = Hash[(:a..:z).to_a.zip((1..26).to_a)]
string_time = Benchmark.realtime do
1000_000.times { string_AZ["r"] }
end
symbol_time = Benchmark.realtime do
1000_000.times { symbol_AZ[:r] }
end
puts "String time: #{string_time} seconds."
puts "Symbol time: #{symbol_time} seconds."
ผลลัพธ์คือ:
String time: 0.21983 seconds.
Symbol time: 0.087873 seconds.
ใช้สัญลักษณ์เป็นตัวระบุคีย์แฮช
{key: "value"}
สัญลักษณ์ช่วยให้คุณสามารถเรียกใช้เมธอดในลำดับอื่นได้
def เขียน (ไฟล์:, data:, โหมด: "ascii") # ถูกลบออกเพื่อความกะทัดรัด จบ เขียน (ข้อมูล: 123, ไฟล์: "test.txt")
ตรึงเพื่อเก็บเป็นสตริงและบันทึกหน่วยความจำ
label = 'My Label'.freeze
/
(หลังstrings
) ออกจากลิงค์ นี่คือ: www.reactive.io/tips/2009/01/11/the-difference-between-ruby- สัญลักษณ์และสตริง