String biểu diễn text mutable; Symbol biểu diễn identifier/name immutable.
1 | "status" == "status" # => true |
Dùng Symbol khi
- key nội bộ ổn định;
- tên method, state, option;
- value thuộc tập identifier nhỏ.
1 | user.public_send(:name) |
Dùng String khi
- text từ user/network/file;
- cần encoding, nối, replace, format;
- số lượng value động/lớn.
1 | name = params[:name].to_s |
Memory myth
Ruby hiện đại garbage-collect dynamic symbols, nên câu “symbol không bao giờ được GC” không còn đúng chung. Dù vậy, convert input tùy ý thành symbol vẫn không cần thiết và có thể tăng memory:
1 | # Không nên nếu key không được kiểm soát |
Allowlist key hoặc giữ string.
Performance
Symbol comparison có thể rẻ vì identity ổn định, nhưng application performance hiếm khi được cứu bởi đổi vài hash key. Database, network và allocation lớn thường đáng đo trước.
Chọn theo semantics:
- identifier → Symbol;
- nội dung → String.
Nếu phải giải thích value này là text hay label, loại dữ liệu nên trả lời trước benchmark. Micro-optimization khi domain chưa rõ là chạy rất nhanh về sai hướng.