سؤال

لقد تساءلت كثيرًا عن هذا، هل هناك تكلفة أداء لتقسيم سلسلة على عدة أسطر لزيادة إمكانية القراءة عند تعيين قيمة لسلسلة في البداية.أعلم أن السلاسل غير قابلة للتغيير وبالتالي يجب إنشاء سلسلة جديدة في كل مرة.كما أن تكلفة الأداء ليست ذات صلة في الواقع بفضل الأجهزة السريعة جدًا الموجودة اليوم (إلا إذا كنت في حلقة شيطانية ما).لذلك على سبيل المثال:

String newString = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";

كيف يتعامل برنامج التحويل البرمجي JVM أو .Net والتحسينات الأخرى مع هذا الأمر.هل سيتم إنشاء سلسلة واحدة؟أم أنها ستنشئ سلسلة واحدة ثم سلسلة جديدة لتسلسل القيمة ثم سلسلة أخرى لتسلسل القيم مرة أخرى؟

هذا من أجل فضولي الخاص.

هل كانت مفيدة؟

المحلول

وهذا حق يكفله C # المواصفات لتكون مطابقة لخلق سلسلة في حرفي واحد، لأنه ثابت وقت الترجمة. من القسم 7.18 من المواصفات C # 3:

<اقتباس فقرة>   

ومتى يفي تعبير ل   متطلبات المذكورة أعلاه،   يتم تقييم التعبير في   وقت الترجمة. وهذا صحيح حتى لو كان   التعبير هو تعبير الفرعي ل   أكبر تعبير يحتوي   بنيات غير ثابتة.

و(انظر المواصفات للحصول على التفاصيل الدقيقة ل"المتطلبات المذكورة أعلاه":)

واللغة مواصفات جاوة يحدد ذلك بالقرب من أسفل قسم 3.10.5 :

<اقتباس فقرة>   

وسلاسل حسابها بواسطة ثابت   يتم حساب تعبيرات (§15.28) في   تجميع الوقت وبعد ذلك تعامل كما لو   كانت حرفية.

نصائح أخرى

في الواقع، في Java، سيقوم المترجم بتحويل ملف String إلى ثابت.

class LongLongString
{
    public LongLongString()
    {
        String newString = "This is a really long long long long long" +
            " long long long long long long long long long long long long " +
            " long long long long long long long long long string for example.";
    }

    public static void main(String[] args)
    {
        new LongLongString();
    }
}

يتم تجميعها في:

Compiled from "LongLongString.java"
class LongLongString extends java.lang.Object{
public LongLongString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   ldc #2; //String This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example.
   6:   astore_1
   7:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #3; //class LongLongString
   3:   dup
   4:   invokespecial   #4; //Method "<init>":()V
   7:   pop
   8:   return

}

كما يمكن أن نرى، يتم تحميل سطر واحد في السطر 4، بدلاً من تحميل عدة سطر String المثيلات التي يتم تحميلها.

يحرر: تم تجميع الملف المصدر باستخدام javac الإصدار 1.6.0_06.انظر الى مواصفات لغة جافا، الطبعة الثالثة, ، (ونفس الباب المذكور في إجابة جون سكيت)، لم أتمكن من العثور على أي مرجع حول ما إذا كان يجب على المترجم أن يقوم بتسلسل أسطر متعددة String في واحد String, ، لذلك من المحتمل أن يكون هذا السلوك خاصًا بتنفيذ برنامج التحويل البرمجي.

واختبار هذا لنفسك. في C # رمز (أن يعادل جافا تعمل أيضا):

string x = "A" + "B" + "C";
string y = "ABC";

bool same = object.ReferenceEquals(x, y); // true

وسوف نرى أن النتيجة هي true.

وبوصفها جانبا، وسترون أن السلسلة يتم اعتقالهم أيضا في تجمع سلسلة وقت التشغيل ل:

bool interned = object.ReferenceEquals(x, string.Intern(x)); // true

ولا المقايضة الأداء. سوف الأمثل مترجم لدمج هذا إلى سلسلة واحدة (على الأقل في جاوة).

وبقدر ما أستطيع أن أتذكر، وهذا لن يخلق سلاسل متعددة، مجرد واحد.

وو. NET IL يعادل تكمل <لأ href = "https://stackoverflow.com/questions/601804/what-is-the-performance-cost-of-assigning-a-single-string-value-using -s / 601824 # 601824 "> coobird في الإجابة :

لC # رمز:

string s = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";
Console.WriteLine(s);

وتجميع التصحيح تنتج:

.method public hidebysig static void Main(string[] args) cil managed
{
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
  .maxstack 1
  .locals init (
      [0] string str)
  L_0000: ldstr "This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example."
  L_0005: stloc.0 
  L_0006: ldloc.0 
  L_0007: call void [mscorlib]System.Console::WriteLine(string)
  L_000c: ret 
}

وهكذا، وكما ترون، انها سلسلة واحدة.

وطالما كل السلاسل ثابتة (كما هي الحال في المثال الخاص بك)، في جافا (وأتصور C #) المترجم تحويل هذا إلى سلسلة واحدة.

ويمكنك فقط الحصول على مشكلات الأداء مع + إذا قمت لسلسلة الكثير من سلاسل الحيوية، مثل في حلقة. في هذه الحالة استخدام ب StringBuilder أو StringBuffer.

تنويه: هذا صحيح بالنسبة لجاوة. وأود أن نفترض معناه الحقيقي لج #

وليس فقط سوف javac إنشاء سلسلة واحدة ولكن سوف JVM استخدام سلسلة واحدة لجميع سلسلة الأخرى التي تحتوي على النص نفسه.

String a = "He" + "llo th"+ "ere";
String b = "Hell" + "o the"+ "re";
String c = "Hello" +" "+"there";
assert a == b; // these are the same String object.
assert a == c; // these are the same String object.

ملحوظة: أنها ستكون نفس الكائن سلسلة في وقت التشغيل حتى إذا كانوا في فئات مختلفة في JARS مختلفة، وقد تم تجميعها من قبل المجمعين مختلفة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top