تُستخدم المقارنة النصية ثلاثية الاتجاه على نطاق واسع في البرمجة (دليل 1 ودليل 2). لكن حتى الآن (Go 1.19)، فإن دالة strings.Compare في الحزمة القياسية مُنفَّذة (عمداً) بطريقة غير مُحسَّنة:
func Compare(a, b string) int {
// ملاحظة(rsc): هذه الدالة لا تستدعي دالة cmpstring في وقت التشغيل،
// لأننا لا نريد تقديم أي مبرر أدائي لاستخدام strings.Compare.
// أساساً، لا ينبغي لأحد أن يستخدم strings.Compare.
// وكما يقول التعليق أعلاه، فهي موجودة هنا فقط للتماثل مع الحزمة bytes.
// إذا كان الأداء مهماً، فينبغي تغيير المصرِّف ليتعرف على النمط
// حتى تستفيد كل الشيفرة التي تجري مقارنات ثلاثية الاتجاه، وليس فقط الشيفرة
// التي تستخدم strings.Compare.
if a == b {
return 0
}
if a < b {
return -1
}
return +1
}
عند مقارنة نصين غير متساويين، سيُجري هذا التنفيذ عمليتَي مقارنة. بينما يحتاج التنفيذ المثالي إلى عملية واحدة فقط، تماماً مثل تنفيذ bytes.Compare الموضح أدناه، والذي تُنفَّذ فيه bytealg.Compare باستخدام شيفرة التجميع على معظم المعماريات.
func Compare(a, b []byte) int {
return bytealg.Compare(a, b)
}
تنفيذ strings.Compare غير فعّال نسبياً. وتحديداً، يكون أقل فعّالية عندما يكون معامَلا النص غير متساويين لكن طوليهما متساويان.
تُظهر شيفرة قياس الأداء باستمرار أن strings.Compare تستهلك ضعف وقت المعالج الذي تستهلكه bytes.Compare عند مقارنة تسلسلات بايتات غير متساوية ومتساوية الطول (ننظر هنا إلى كلٍّ من النصوص وشرائح البايتات على أنها تسلسلات بايتات).
التعليق الداخلي لتنفيذ strings.Compare الحالي مثير للاهتمام بعض الشيء. يقترح التعليق ألا نستخدم strings.Compare في Go على الإطلاق، لكن لا توجد حتى الآن طرق فعّالة بديلة (ومن المفارقات أن هذه الدالة تُستخدم في شيفرة سلسلة أدوات Go وتوصي بها إحدى دوال الحزمة القياسية). ويذكر أنه ينبغي للمصرِّف إجراء تحسينات خاصة لتحويل الشيفرة التي تستخدم معامِلات المقارنة تلقائياً إلى مقارنات ثلاثية الاتجاه مُحسَّنة داخلياً إن أمكن. ومع ذلك، لم تُجرَ مثل هذه التحسينات في المصرِّف قط، ولا توجد خطط لإجراء مثل هذه التحسينات حتى الآن على حد علمي. شخصياً، أشك في أن مثل هذه التحسينات قابلة للتنفيذ في كل حالة استخدام. لذا أرى أنه ينبغي تنفيذ strings.Compare بكفاءة، لتجنب خيبة توقعات المستخدمين.
(هذه واحدة من أكثر من 101 حقيقة واقتراح وردت في كتاب Go Optimizations 101.)
تحديث: اطّلع على النقاشات على reddit وHN.
تحديث 2: أخيراً، حُسِّنت دالة strings.Compare في Go 1.23.