Fallout New Vegas
Quest script vs UDF

Image information

Added on

Uploaded by

Xilandro

About this image

Because arguing never stops. And I saw some people throwing poopoo at me for using GameMode quest scripts with fast delay, and "oh no too much code why not move it into UDF?"
So this is it. UDFs are executed in a single line, which is way heavier than normal quest (or even effect) script running with lowest possible delay in GameMode
Case closed. Your fancy UDF mods are slow(er).

Tests made with Code Comparer by Cipscis

18 comments

  1. miguick
    miguick
    • premium
    • 459 kudos
    Ok, I've seen the image, read the comments, and just want to say I now feel like an old war criminal getting hit by the realization of all the "atrocities" I've made in my scripting career. If anyone reads this, treat my mods with several grains of salt. I'm too burned on scripting to do much about it now.
    1. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      Yeah, nobody would go and rewrite entire mods (well, unless it has serious performance issues and gains from rewriting are bigger than time&effort). It's more of an advice for anything in the future.
  2. DaWrecka
    DaWrecka
    • member
    • 23 kudos
    Here's a thought that occurred to me after reading this thread... How does
    let x += y
    compare to
    set x to x + y
    ?

    Or -=, or /= or *=, for that matter.
    1. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      set will be faster.
  3. hexef
    hexef
    • premium
    • 87 kudos
    I don't understand the numbers below Quest and UDF. At first glance I thought it was the time executed but then I read the description and I realised that it must be something else.
    1. VariableEagle
      VariableEagle
      • supporter
      • 59 kudos
      I'd love a clarification as well. Is it frame rate?
    2. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      Yeah, it's a framerate.
    3. hexef
      hexef
      • premium
      • 87 kudos
      So it's framerate, huh. I had no idea that UDFs could be so inefficient compared to other type of scripts. Though, I'd rather sacrifice some performance in order to keep my scripts' code readable, therefore I am still going to stick with UDFs.

      Thank you for posting this, Xil.
    4. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      also it's worth nothing this was a return (SetFunctionValue) function. It's significantly slower than some sort of standalone UDF without return.
      Problem is - it all adds up eventually, mod after mod.
      But you are free to use whatever you want, just keep in mind that people don't read your code. People *play it*.
    5. VariableEagle
      VariableEagle
      • supporter
      • 59 kudos
      Oof, that's a huge cost in frames then. And here I was thinking I was so cool for hooking everything to Events and UDFs in my last upload. At least in that case, everything only fires one time on a save load, when in MCM MenuMode or while transitioning in/out of MenuMode. I hope those are situations where UDFs are good practice rather than inefficient.
    6. hexef
      hexef
      • premium
      • 87 kudos
      people don't read your code. People *play it*.

      But you are doing your future self a favor. I can't remember how many times I came back to a mod that I've made years ago and couldn't understand jack s#*! from the code. UDFs really help me in structuring the flow of my scripts.

      Btw, I noticed you don't use the let keyword for assignments. I always use it because if some operation fails, you are informed in the console. With set, it will be a silent fail. But I guess you already know this so... any reason for that?
    7. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      set on the left, let on the right.
      https://i.imgur.com/zHr9i64.jpg
    8. hexef
      hexef
      • premium
      • 87 kudos
      Hmm, very interesting. I had a hunch that performance was the reasoning behind your preference. I guess it's the error checking that makes let slower. I should give up on using let unless there are operations that involve references or divisions, especially divisions.

      From my experience, I can firmly say that let has probably saved me from tens of hours of debugging. That's because it discovered many division by zero errors. Errors that I would have never caught with set.

      Still, for operations such as "let var += 1", I think you would be better off just typing "set var to var + 1". I can't see how that would ever fail.
    9. tgspy
      tgspy
      • premium
      • 188 kudos
      It's best to use Let for NVSE aware operations, like array building and such.
    10. MildlyFootwear
      MildlyFootwear
      • premium
      • 30 kudos
      A bit late, but I think it's still worth sharing.
      In one of my mods I am using a user-defined function to calculate fully modded DPS on a weapon. I've sorted 5 arrays containing ~60 weapons each multiple times with two different functions for it, one using mainly set (https://pastebin.com/U3aKZrpd) and the other using only let (https://pastebin.com/LLzMqsMa). It would consistently take 6-7 seconds to complete using let, but using set it was under 2 seconds every time I tried.
    11. hexef
      hexef
      • premium
      • 87 kudos
      Jesus, I really ought to stop using so many unnecessary lets. I expected to see a difference with hundreds of let operations, and your script only had like 14. Still, 9 of them were inside an iteration, which kinda explains the huge performance gain.
    12. MildlyFootwear
      MildlyFootwear
      • premium
      • 30 kudos
      So even though the script only has 14, the script itself is being run in the neighborhood of 4000 times since the array sorting function provided by NVSE (from my inbetween script) uses it on each item against each other item (without comparing inbetween arrays and afaik not repeating if it has already done a comparison).
      I was quite surprised by the difference, though. Taking into account the delays added by every other function, "set" is probably in the ballpark of 8x faster than "let".
    13. Xilandro
      Xilandro
      • premium
      • 2,421 kudos
      Now imagine my face when I see somebody quite respected in the community and skilled in scripting, telling people something like "there is no reason to not to use let, it's great, use it love it admire it".
      Well sure it would not be a problem if our modusers were using limited amount of scripted mods, choose them wisely, and so on. But no, what we see is a picture of 130-death limit amount mods, lots of them merged, and topped with Solid. That's a recipe for disaster. One mod uses let by default, several others just pump the game with UDFs, few more just pure heavy math ones - and there you have it, low fps and instability all over the place. Because it all adds up.
      Don't get me wrong, I'm not saying "stop drop and roll, forget about UDFs, let, events, them all bad", no. But if you don't need it (or if you need it solely for readability) - don't do it. Keep it simple, use slicing to speed it up, comment it well (if you need to navigate it easily in the future).
      I guess only one solid "NEVER DO IT" is SetFunctionValue SomeValueOrRef inside UDF. It's a killer, you see the result on the picture. Use Set QuestName.MyReturnValueOrRef to SomeValueOrRef instead. It's insanely faster.