สร้างตัวแปรหรือวิธีการโทรสองสามครั้ง - ไหนดีกว่ากัน?

ฉันสงสัยเกี่ยวกับการสร้างตัวแปรใหม่หรือวิธีการเรียกสองสามครั้ง อะไรจะดีไปกว่าประสิทธิภาพโดยรวมและการทำความสะอาด GC ลองดูสิ:

public static string GetValue(RegistryKey key, string value)
{
    if (key.GetValue(value) == null)
        return null;
    string newValue = key.GetValue(value).ToString();
    if (String.IsNullOrWhiteSpace(newValue))
        return null;
    return newValue.ToLower();
}

ฉันจะทำให้รหัสนี้ชัดเจนได้อย่างไร


person xNombre    schedule 24.04.2015    source แหล่งที่มา
comment
ไม่น่าจะเป็นเช่นนั้น คุณไม่สามารถบอกได้ว่าคอมไพเลอร์จะทำอะไรเพื่อเพิ่มประสิทธิภาพโค้ดของคุณ   -  person Erik Philips    schedule 24.04.2015
comment
StackOverflow เป็นเรื่องเกี่ยวกับปัญหาการเขียนโปรแกรมเฉพาะ หากคุณต้องการพูดคุยเกี่ยวกับคุณภาพของโค้ด โปรดไปที่ การตรวจสอบโค้ด โปรดตรวจสอบหน้าวิธีการถามก่อนที่จะโพสต์ที่นั่น (อย่างที่คุณควรจะทำที่นี่)   -  person Pierre-Luc Pineault    schedule 24.04.2015
comment
ฉันเดาว่ามันเป็นการเพิ่มประสิทธิภาพก่อนกำหนดโดยไม่จำเป็น ในกรณีส่วนใหญ่ คุณควรใช้ตัวสร้างโปรไฟล์เพื่อค้นหาปัญหาคอขวดและเพิ่มประสิทธิภาพ   -  person Pavel Oganesyan    schedule 24.04.2015
comment
นี่ไม่ใช่กรณีของการเพิ่มประสิทธิภาพก่อนเวลาอันควร ถ้าเมธอด RegistryKey.GetValue ไม่แคชผลลัพธ์ การเรียกนี้จะต้องมีการเข้าถึงรีจิสทรี ซึ่งมี ลำดับความสำคัญ ช้ากว่าการเข้าถึงตัวแปรในเครื่องหลายระดับ   -  person Douglas    schedule 24.04.2015


คำตอบ (3)


โดยทั่วไป เมื่อคุณจำเป็นต้องใช้ผลลัพธ์ของการเรียกใช้เมธอดหลายครั้ง คุณควรกำหนดให้กับตัวแปรท้องถิ่นก่อน ตัวแปรโลคัลต้องการให้สแต็กเฟรมของเมธอดของคุณมีขนาดใหญ่ขึ้นสองสามไบต์ (8 ไบต์สำหรับตัวแปรอ็อบเจ็กต์บน 64 บิต) และจะถูกล้างโดยอัตโนมัติเมื่อเมธอดส่งคืน ซึ่งไม่มีผลกระทบต่อ GC

ในทางกลับกัน การเรียกใช้เมธอดซ้ำจะต้องใช้ตรรกะทั้งหมดเพื่อดำเนินการอีกครั้ง ซึ่งทำให้เกิดการจัดสรรเฟรมสแต็กที่ต้องการ และอาจสร้างอินสแตนซ์ของอ็อบเจ็กต์ได้ ในกรณีของคุณ RegistryKey.GetValue ทำให้สถานการณ์แย่ลงไปอีก เนื่องจากจำเป็นต้องเข้าถึงรีจิสทรีของ Windows ซึ่งทำให้ช้ากว่าการเข้าถึงตัวแปรในเครื่องหลายลำดับ นอกจากนี้ คุณอาจเผชิญกับสภาวะการแข่งขันที่การโทรทั้งสองส่งคืนค่าต่างกัน

public static string GetValue(RegistryKey key, string name)
{
    object value = key.GetValue(name);
    if (value == null)
        return null;
    string valueStr = value.ToString()
    if (String.IsNullOrWhiteSpace(valueStr))
        return null;
    return valueStr.ToLower();
}

โปรดทราบว่าปัญหานี้จะได้รับการแก้ไขเป็นส่วนใหญ่ใน C# 6 ซึ่งคุณสามารถใช้ตัวดำเนินการแบบมีเงื่อนไขว่างได้:

public static string GetValue(RegistryKey key, string name)
{
    string value = key.GetValue(name)?.ToString();
    if (String.IsNullOrWhiteSpace(value))
        return null;
    return value.ToLower();
}
person Douglas    schedule 24.04.2015
comment
ว้าว ด้วย C# 6 มันจะเป็นเค้กชิ้นหนึ่งเลย! ตามที่ฉันเข้าใจ '?' จะส่งคืนค่า null-string-value หากจำเป็น? - person xNombre; 24.04.2015
comment
a?.Foo() จะประเมินเป็น null ทันทีหาก ​​a คือ null มันจะเรียกใช้ (และส่งคืนผลลัพธ์ของ) a.Foo() ถ้า a ไม่ใช่ null - person Douglas; 24.04.2015

สร้างตัวแปรท้องถิ่นและเรียกใช้เมธอดหนึ่งครั้ง มีค่าใช้จ่าย (เล็กน้อยที่เป็นที่ยอมรับ) สำหรับการเรียกเมธอดในเครื่อง หากคุณใช้วิธีระยะไกล การเรียกความแตกต่างจะเด่นชัดกว่ามาก

person Kevin    schedule 24.04.2015

โดยใช้ ? โอเปอเรเตอร์ทำให้อ่านง่ายขึ้นและประสิทธิภาพดีขึ้นอย่างที่คุณเห็น

public static string GetValue(RegistryKey key, string value)
{
    string valueStr=(string)key.GetValue(value);
    return string.IsNullOrWhiteSpace(valueStr)?null:valueStr.ToLower();
}
person M.kazem Akhgary    schedule 24.04.2015
comment
เหตุใดคุณจึงถือว่าตัวดำเนินการที่ประกอบด้วยสามมีประสิทธิภาพดีกว่า - person Yuval Itzchakov; 26.04.2015
comment
เลขที่. ฉันหมายถึงประสิทธิภาพที่ดีขึ้นสำหรับการแคสต์ไปยังสตริงโดยตรง...น้อยกว่าหากเปรียบเทียบกับโค้ด OP ฉันไม่คิดว่าจะใช้ if else หรือ ? ส่งผลต่อผลงานมากขนาดนั้น@YuvalItzchakov - person M.kazem Akhgary; 26.04.2015