مرحبا مرة اخرى كما كتبنا بالفعل ، في الأسبوع المقبل ، ستبدأ مجموعة جديدة من الدورات التدريبية حول
"Java Developer" ، وفقًا للتقاليد المعمول بها ، وسنشارك معك ترجمة مواد مثيرة للاهتمام حول هذا الموضوع.
بدءًا من JDK 9 ، خضع تسلسل السلسلة لتغييرات مهمة.تم تنفيذ JEP 280 ("Indify String Concatenation") كجزء من
JDK 9 ، ووفقًا لقسم الملخص: "يغير تسلسل كود bytecode لتسلسل سلسلة
javac الذي تم إنشاؤه لاستخدام مكالمات
invokedynamic لوظائف مكتبة JDK." يُلاحظ بسهولة تأثير ذلك على تسلسل السلسلة في Java من خلال النظر إلى إخراج
javap للفئات التي تستخدم تسلسل السلسلة التي تم تجميعها في JDK قبل JDK 9 وبعد JDK 9.

في العرض الأول ، سيتم استخدام فئة Java بسيطة تسمى "HelloWorldStringConcat".
package dustin.examples; import static java.lang.System.out; public class HelloWorldStringConcat { public static void main(final String[] arguments) { out.println("Hello, " + arguments[0]); } }
فيما يلي مقارنة بين الاختلافات الخاصة بإخراج javap -verbose لطريقة
main(String)
لفئة HelloWorldStringConcat عند التحويل البرمجي مع JDK 8
(AdoptOpenJDK) و JDK 11
(Oracle OpenJDK) . سلطت الضوء على بعض الاختلافات الرئيسية.
JDK 8 javap الإخراج Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringConcat.class Last modified Jan 28, 2019; size 625 bytes MD5 checksum 3e270bafc795b47dbc2d42a41c8956af Compiled from "HelloWorldStringConcat.java" public class dustin.examples.HelloWorldStringConcat minor version: 0 major version: 52 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #2
JDK 11 javap الإخراج Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringConcat.class Last modified Jan 28, 2019; size 908 bytes MD5 checksum 0e20fe09f6967ba96124abca10d3e36d Compiled from "HelloWorldStringConcat.java" public class dustin.examples.HelloWorldStringConcat minor version: 0 major version: 55 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: getstatic #2
يصف قسم "الوصف" في
JEP 280 هذا الاختلاف: "الفكرة هي استبدال رقصة الانضمام إلى StringBuilder بأكملها
invokedynamic
استدعاء بسيطة إلى
java.lang.invoke.StringConcatFactory ، والتي ستأخذ القيم التي يجب دمجها." يُظهر القسم نفسه مقارنة مماثلة للإخراج المترجم لمثال تسلسل سلسلة مماثل.
الإخراج المترجم مع JDK 11 لسهولة التسلسل ليس مجرد خطوط أقل من الإخراج من JDK 8 ؛ لديه أيضا عدد أقل من "باهظة الثمن" العمليات. يمكن تحقيق تحسينات محتملة في الأداء بسبب عدم الحاجة إلى التفاف أنواع بدائية ولا تحتاج إلى إنشاء العديد من الكائنات الإضافية. أحد الدوافع الرئيسية لهذا التغيير هو "إرساء الأساس لإنشاء معالجات محسّنة لسلسلة السلسلة والتي يتم تنفيذها دون الحاجة إلى تغيير برنامج التحويل البرمجي من Java-to-bytecode" و "تمكين تحسينات تسلسل السلسلة في المستقبل دون تغييرات إضافية على الكود الذي تم إنشاؤه بواسطة javac. "
هناك نتيجة مثيرة للاهتمام لهذا من حيث استخدام
StringBuffer (والتي
أجد صعوبة في العثور على استخدام جيد لأي حال) و
StringBuilder . في JEP 280 ، ذكرت "Non-Goal" عدم "تقديم أي واجهات برمجة تطبيقات جديدة لـ String و / أو StringBuilder يمكن أن تساعد في إنشاء استراتيجيات ترجمة أكثر كفاءة." في هذا الصدد ، بالنسبة لسلسلة السلسلة البسيطة ، كما في المثال في بداية هذا المنشور ، يستبعد الاستخدام الصريح لـ StringBuilder و StringBuffer المترجم فعليًا من استخدام الميزة المقدمة في
JEP 280 ، والتي نناقشها في هذا المنشور.
تعرض القائمتان التاليتان تطبيقات مماثلة للتطبيق البسيط الموضح أعلاه ، ولكن بدلاً من السلاسل المتسلسلة ، يستخدمون StringBuilder و StringBuffer على التوالي. عند تنفيذ javap -verbose لهذه الفئات بعد تجميعها مع JDK 8 ومع JDK 11 ، لا توجد فروق ذات دلالة إحصائية في الطرق الرئيسية (String []).
الاستخدام الصريح لـ StringBuilder في JDK 8 و JDK 11 هو نفسه package dustin.examples; import static java.lang.System.out; public class HelloWorldStringBuilder { public static void main(final String[] arguments) { out.println(new StringBuilder().append("Hello, ").append(arguments[0]).toString()); } }
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringBuilder.class Last modified Jan 28, 2019; size 627 bytes MD5 checksum e7acc3bf0ff5220ba5142aed7a34070f Compiled from "HelloWorldStringBuilder.java" public class dustin.examples.HelloWorldStringBuilder minor version: 0 major version: 52 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #2
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringBuilder.class Last modified Jan 28, 2019; size 627 bytes MD5 checksum d04ee3735ce98eb6237885fac86620b4 Compiled from "HelloWorldStringBuilder.java" public class dustin.examples.HelloWorldStringBuilder minor version: 0 major version: 55 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #2
الاستخدام الصريح لـ StringBuffer في JDK 8 و JDK 11 هو نفسه package dustin.examples; import static java.lang.System.out; public class HelloWorldStringBuffer { public static void main(final String[] arguments) { out.println(new StringBuffer().append("Hello, ").append(arguments[0]).toString()); } }
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringBuffer.class Last modified Jan 28, 2019; size 623 bytes MD5 checksum fdfb90497db6a3494289f2866b9a3a8b Compiled from "HelloWorldStringBuffer.java" public class dustin.examples.HelloWorldStringBuffer minor version: 0 major version: 52 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #2
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringBuffer.class Last modified Jan 28, 2019; size 623 bytes MD5 checksum e4a83b6bb799fd5478a65bc43e9af437 Compiled from "HelloWorldStringBuffer.java" public class dustin.examples.HelloWorldStringBuffer minor version: 0 major version: 55 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=1, args_size=1 0: getstatic #2
JDK 8 و JDK 11 معالجة سلسلة سلاسل Loopedللحصول على مثال أخير للتغييرات التي تم إجراؤها على JEP 280 أثناء العمل ، يمكنني استخدام نموذج تعليمة برمجية يمكن أن يكسر قابلية بعض مطوري Java وسلاسل السلسلة في حلقة. ضع في اعتبارك أن هذا مجرد مثال توضيحي ، وسيكون كل شيء على ما يرام ، ولكن لا تحاول تكراره في المنزل.
package dustin.examples; import static java.lang.System.out; public class HelloWorldStringConcatComplex { public static void main(final String[] arguments) { String message = "Hello"; for (int i=0; i<25; i++) { message += i; } out.println(message); } }
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringConcatComplex.class Last modified Jan 30, 2019; size 766 bytes MD5 checksum 772c4a283c812d49451b5b756aef55f1 Compiled from "HelloWorldStringConcatComplex.java" public class dustin.examples.HelloWorldStringConcatComplex minor version: 0 major version: 52 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: ldc #2
Classfile /C:/java/examples/helloWorld/classes/dustin/examples/HelloWorldStringConcatComplex.class Last modified Jan 30, 2019; size 1018 bytes MD5 checksum 967fef3e7625965ef060a831edb2a874 Compiled from "HelloWorldStringConcatComplex.java" public class dustin.examples.HelloWorldStringConcatComplex minor version: 0 major version: 55 . . . public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: ldc #2
في العرض التقديمي
"Enough java.lang.String to Hang Ourselves ..." ،
ناقش الدكتور
هاينز م. كابوتز وديمتري فيازيلينكو التغييرات التي تم إجراؤها على تسلسل سلسلة جافا وتلخيصها لفترة وجيزة ، "+ المزيد لم يتم تجميعها في StringBuilder ". في الشريحة "الدروس المستفادة من اليوم" ، يشيرون إلى: "استخدام + بدلاً من StringBuilder حيثما كان ذلك ممكنًا" و "إعادة ترجمة الطبقات لـ Java 9+."
التغييرات التي تم تنفيذها في JDK 9 مع
JEP 280 ، "ستسمح في المستقبل بتحسين تسلسل السلسلة ، دون الحاجة إلى تغييرات إضافية في الرمز الثانوي الذي تم إنشاؤه بواسطة javac." ومن المثير للاهتمام ، أنه تم الإعلان مؤخرًا عن أن JEP 348 ("Java Compiler Intrinsics for JDK APIs") أصبحت الآن مرشحة لـ JEP ، وهدفها هو استخدام نهج مماثل لتجميع
String :: format و
Objects::hash
.
ما رأيك هو مقال مفيد؟ نحن في انتظار تعليقاتكم وندعو الجميع
ليوم مفتوح في دورة Java Developer ، التي ستعقد في 25 مارس من قبل المدير العام لـ OTUS -
Vitaly Chibrikov .