ความแตกต่างของประสิทธิภาพระหว่าง IIf () และ If


คำตอบ:


140

VB มีข้อความต่อไปนี้Ifซึ่งคำถามอ้างถึงฉันคิดว่า:

' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")

ตัวแรกเป็นตัวดำเนินการตามเงื่อนไขของ C # โดยทั่วไปและตัวที่สองคือตัวดำเนินการรวมกัน (ส่งคืนresultเว้นแต่จะเป็นNothingในกรณีนี้จะกลับมา"Alternative") Ifจึงได้เข้ามาแทนที่IIfและหลังล้าสมัย

เช่นเดียวกับใน C # Ifการลัดวงจรของตัวดำเนินการตามเงื่อนไขของ VB ดังนั้นตอนนี้คุณสามารถเขียนสิ่งต่อไปนี้ได้อย่างปลอดภัยซึ่งไม่สามารถทำได้โดยใช้IIfฟังก์ชัน:

Dim len = If(text Is Nothing, 0, text.Length)

3
คุณไม่ได้ตอบคำถามประสิทธิภาพและไม่ได้กล่าวถึงผลข้างเคียงของIIf.
ก.ค.

2
@jor ย่อหน้าสุดท้ายของคำตอบของฉันเกี่ยวกับผลข้างเคียง ประสิทธิภาพไม่เกี่ยวข้องจริงๆเมื่อตัวเลือกใดตัวเลือกหนึ่งล้าสมัย สำหรับสิ่งที่คุ้มค่าตัวดำเนินการแบบเนทีฟIfนั้นมีประสิทธิภาพมากกว่าIIfฟังก์ชันโดยไกล
Konrad Rudolph

2
@mmcrae ถูกต้องและตรงจุดประสงค์: ดังที่ฉันได้กล่าวไปแล้ว IIf ล้าสมัยดังนั้นจึงไม่ค่อยมีเหตุผลที่จะพูดคุยกัน ที่กล่าวว่าย่อหน้าสุดท้ายของฉันจะกล่าวถึงความแตกต่างที่เกี่ยวข้อง นั่นคือทั้งหมดที่คุณต้องรู้จริงๆ
Konrad Rudolph

2
ฉันขอขอบคุณที่คุณต้องการสนับสนุนมาตรฐานที่ดีและให้แน่ใจว่ามือใหม่จะไม่ยอมรับการปฏิบัติที่ไม่ดี แต่บางคนอาจมีปัญหาที่ถูกต้องตามกฎหมายที่ทำให้พวกเขาต้องการที่จะเข้าใจความแตกต่างให้ดีขึ้น ... เช่นการรักษารหัสเดิมการติดอยู่กับ เครื่องมืออื่น ๆ ที่ใช้มัน ฯลฯ และThat's all you need to know, reallyฟังดูไม่เป็นทัศนคติที่เอื้อสำหรับเว็บไซต์ที่อุทิศให้กับการแบ่งปันความรู้)
Don Cheadle

1
@mmcrae โอ้ฉันไม่ได้ตั้งใจที่จะไม่สนใจฉันแค่หมายความว่าภายในของ IIf เป็นเรื่องเล็กน้อยที่น่าเบื่อ มันมีเพียงคำสั่ง If ธรรมดาซึ่งหมายความว่าโค้ดชิ้นสุดท้ายในคำตอบของฉันจะไม่ทำงาน
Konrad Rudolph

65

IIf()รันทั้งรหัสจริงและเท็จ สำหรับเรื่องง่ายๆเช่นการกำหนดตัวเลขนี่ไม่ใช่เรื่องใหญ่ แต่สำหรับโค้ดที่ต้องใช้การประมวลผลประเภทใดก็ตามคุณกำลังเสียรอบการรันเงื่อนไขที่ไม่ตรงกันและอาจทำให้เกิดผลข้างเคียง

ภาพประกอบรหัส:

Module Module1
    Sub Main()
        Dim test As Boolean = False
        Dim result As String = IIf(test, Foo(), Bar())
    End Sub

    Public Function Foo() As String
        Console.WriteLine("Foo!")
        Return "Foo"
    End Function

    Public Function Bar() As String
        Console.WriteLine("Bar!")
        Return "Bar"
    End Function
End Module

ผลลัพธ์:

Foo!
Bar!

13

นอกจากนี้ปัญหาใหญ่อีกประการหนึ่งของ IIf คือมันจะเรียกใช้ฟังก์ชันใด ๆ ที่อยู่ในอาร์กิวเมนต์ [1] ดังนั้นหากคุณมีสถานการณ์ดังต่อไปนี้:

string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)

มันจะทำให้เกิดข้อยกเว้นซึ่งไม่ใช่วิธีที่คนส่วนใหญ่คิดว่าฟังก์ชันนี้ใช้งานได้ในครั้งแรกที่เห็น สิ่งนี้อาจนำไปสู่การแก้ไขข้อบกพร่องที่ยากมากในแอปพลิเคชันเช่นกัน

[1] ฟังก์ชัน IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx


นี่คือเหตุผลว่าทำไมถ้ามาแทนที่ IIF แบบเก่าฉันเคยมีปัญหากับ IIF แต่ถ้าบันทึกเพิ่มโค้ดหลายบรรทัด
NiL

7

ควรใช้ If แทน IIf เพื่อใช้กลไกการอนุมานประเภทอย่างถูกต้อง (Option Infer On)

ในตัวอย่างนี้คำหลักได้รับการยอมรับว่าเป็นสตริงเมื่อฉันใช้ If:

Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)

มิฉะนั้นจะถูกรับรู้ว่าเป็นวัตถุ:

Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)


6

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

นอกจากนี้"IIF เป็นฟังก์ชันเทียบกับ IF ที่เป็นส่วนหนึ่งของไวยากรณ์ของภาษา" ... ซึ่งบอกเป็นนัยว่าถ้าจะเร็วกว่านั้น ... ถ้าไม่มีอะไรอื่นนอกจากนั้นคำสั่ง If สามารถต้มลงได้โดยตรง ไปยังชุดของ opcodes ขนาดเล็กแทนที่จะต้องไปที่พื้นที่อื่นในหน่วยความจำเพื่อดำเนินการตามตรรกะที่พบในฟังก์ชันดังกล่าว อาจเป็นความแตกต่างที่ซ้ำซาก แต่ก็น่าสังเกต


6

ฉันเชื่อว่าความแตกต่างหลักระหว่าง If และ IIf คือ:

  • ถ้า (test [boolean], statement1, statement2) หมายความว่าตามค่าการทดสอบทั้ง satement1 หรือ statement2 จะดำเนินการ (มีเพียงหนึ่งคำสั่งเท่านั้นที่จะดำเนินการ)

  • Dim obj = IIF (test [boolean], statement1, statement2) หมายความว่าทั้งสองคำสั่งจะดำเนินการ แต่ตามค่าทดสอบหนึ่งในนั้นจะคืนค่าเป็น (obj)

ดังนั้นหากคำสั่งใดคำสั่งหนึ่งมีข้อยกเว้นก็จะโยนมันเข้าไปใน (IIf) ต่อไป แต่ใน (If) มันจะโยนมันในกรณีที่เงื่อนไขจะคืนค่า


5

... เหตุใดจึงใช้เวลานานถึง 6x โดยอ้างอิงจาก wiki:

เนื่องจาก IIf เป็นฟังก์ชันไลบรารีจึงต้องใช้ค่าใช้จ่ายในการเรียกฟังก์ชันเสมอในขณะที่ตัวดำเนินการแบบมีเงื่อนไขมีแนวโน้มที่จะสร้างโค้ดแบบอินไลน์

โดยพื้นฐานแล้ว IIf เทียบเท่ากับตัวดำเนินการ ternary ใน C ++ / C # ดังนั้นจึงให้คำสั่ง 1 บรรทัด if / else ที่ดีหากคุณต้องการ คุณยังสามารถกำหนดฟังก์ชันเพื่อประเมินว่าคุณต้องการ


1

ฟังก์ชั่นเหล่านั้นแตกต่างกัน! บางทีคุณอาจต้องใช้คำสั่ง IF เท่านั้น IIF จะช้าลงเสมอเพราะมันจะทำหน้าที่ทั้งสองบวกมันจะทำคำสั่ง IF มาตรฐาน

หากคุณสงสัยว่าทำไมจึงมีฟังก์ชั่น IIF นี่อาจเป็นคำอธิบาย:

Sub main()
    counter = 0
    bln = True
    s = iif(bln, f1, f2)
End Sub

Function f1 As String
    counter = counter + 1
    Return "YES"
End Function

Function f2 As String
    counter = counter + 1
    Return "NO"
End Function

ดังนั้นตัวนับจะเป็น 2 หลังจากนี้ แต่ s จะเป็น "ใช่" เท่านั้น ฉันรู้ว่าสิ่งที่เคาน์เตอร์นี้ไม่มีประโยชน์ แต่บางครั้งก็มีฟังก์ชั่นที่คุณจะต้องใช้ทั้งคู่เพื่อเรียกใช้ไม่ว่า IF จะเป็นจริงหรือเท็จและกำหนดค่าจากค่าใดค่าหนึ่งให้กับตัวแปรของคุณ


หากคุณต้องการให้ทั้งคู่ทำงานคุณควรเรียกทั้งสองอย่างชัดเจนจากนั้นทำมาตรฐาน If การใช้IIf()วิธีนี้จะทำให้คนอ่านโค้ดของคุณสับสน
สนุกสนาน

ฉันไม่ได้ตั้งใจให้ความคิดเห็นนั้นเป็นคำวิจารณ์ ฉันแค่ชี้ให้เห็นว่าการใช้มันในลักษณะนี้ไม่ใช่แนวทางปฏิบัติที่ดี
Spivonious
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.