Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: VB6: IIf kaipaa vaihtoehtoja

Merri [13.07.2006 15:57:56]

#

IIf on kätevähkö toiminto VB:ssä, antaen näppärän yhden rivin syntaksin yksinkertaisille if-lausekkeille. Ongelma on siinä, että se on aivan järkyttävän hidas: sitä ei yksinkertaisesti kannata käyttää missään runsaasti suoritettavassa koodissa.

IIfillä on kaksi selvää ongelmaa: ensinnäkin se käyttää Variant-muuttujatyyppiä. Tämä on "älykäs" ja helppokäyttöinen, mutta samalla järkyttävän hidas muuttujatyyppi.

Toinen ongelma on siinä, että IIf suorittaa molemmat sille annetut lausekkeet, sekä tosi-, että etätosilausekkeen. Alla tästä esimerkki:

Debug.Print IIf(True, MsgBox("Terve!", vbRetryCancel), MsgBox("Näinhän tämä käy.", vbYesNo))

Kun suoritat koodin, huomaat että näet kaksi viestilaatikkoa ja debuggeriin palautuva arvo riippuu siitä, kumpaa nappulaa painoit ensimmäisessä viestilaatikossa. IIf on yksinkertaisesti tavanomainen funktio ja toimii tavanomaisen funktion tapaan; mutta on vielä sitäkin järkyttävästi hitaampi.


Viisaimmat taisivat jo hoksata miten ongelman voi ratkaista: luomalla oman funktion. Siispä olen alle listannut muutaman valmiin funktion ja kukin voi tehdä tarpeidensa mukaan sopivia muuttujatyyppejä itselleen, vaiva on äärimmäisen vähäinen.

Nopeusmittauksissa IIf suoriutui kymmenestä miljoonasta kutsusta reilussa kahdessa ja puolessa sekunnissa (2500 ms). Vastaavasti IfLng selviytyi vastaavasta urakasta kuudessa kymmenessä millisekunnissa (60 ms)! Ero on järkyttävä. Jopa IfVar selviytyi samasta taakasta noin sekunnissa, vaikka on toimintalogiikaltaan täysin yhteensopiva IIf:n kanssa.

Lopputulos: IIf on täysin käyttökelvoton, omalla koodilla selviää samasta tehtävästä paljon nopeammin.

Lisäksi monimutkaisia laskutehtäviä ei kannata antaa IIf:lle, vaan pysyttäytyä erittäin yksinkertaisissa laskuissa tai vain syöttää etukäteen laskettuja/määritettyjä arvoja.

Public Function IfByte(ByVal Expression As Boolean, ByVal TruePart As Byte, ByVal FalsePart As Byte) As Byte
    If Expression Then IfByte = TruePart Else IfByte = FalsePart
End Function
Public Function IfInt(ByVal Expression As Boolean, ByVal TruePart As Integer, ByVal FalsePart As Integer) As Integer
    If Expression Then IfInt = TruePart Else IfInt = FalsePart
End Function
Public Function IfLng(ByVal Expression As Boolean, ByVal TruePart As Long, ByVal FalsePart As Long) As Long
    If Expression Then IfLng = TruePart Else IfLng = FalsePart
End Function
Public Function IfVar(ByVal Expression As Boolean, ByVal TruePart As Variant, ByVal FalsePart As Variant) As Variant
    If Expression Then IfVar = TruePart Else IfVar = FalsePart
End Function

Blaze [18.07.2006 23:04:46]

#

Ai, VB:ssä on tollanenki funkkari. Oppia ikä kaikki. Tosin tämän opin joutuu samantien unohtamaan :P

moptim [21.07.2006 08:02:05]

#

Että tämmösiä...

kayttaja-4976 [05.08.2006 15:56:37]

#

Eikös se ole .NET?

Merri [06.08.2006 03:30:06]

#

Tarkoitatko että löytyisi vain .NETistä? Kyllä tämä ihan VB6:sta löytyy.

Grez [05.02.2017 19:46:15]

#

VB.Netissä (2008 alkaen) voi käyttää ternary-operaattoriakin joka on kuten Iif mutta yhdellä I:llä, jolloin ei tule hitausongelmaa eikä myöskään tämän purkkaratkaisun ongelmaa, että molemmat arvot yhä lasketaan.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta