Running long codes makes Papyrus looks slow...

Post » Wed Jun 20, 2012 2:50 pm

Are there tricks yet to make Papyrus run any faster?

Doing multiple loops on inventory sorting is a nightmare..

It may be Paprus is an external system, and every form has to be made into a property. I dunno. But it just seems to take a very long time to run code with it.

Am I the only person noticing this (so I can just think it's the senses playing havok)?
User avatar
Adam Porter
 
Posts: 3532
Joined: Sat Jun 02, 2007 10:47 am

Post » Wed Jun 20, 2012 7:36 pm

You gave us nothing to go on - no script, no clear intend.
User avatar
Lisa
 
Posts: 3473
Joined: Thu Jul 13, 2006 3:57 am

Post » Wed Jun 20, 2012 7:12 am

Sorry Xetrill, I'm not having an actual issue. I'm just seeing if anyone else has noticed the speed of papyrus... The scripts do what they're supposed to..

I just start rofl when I press an activator that starts sorting away inventory. Manually open my inventory and watch things disappear one by one in real time oh so slowly!
User avatar
Theodore Walling
 
Posts: 3420
Joined: Sat Jun 02, 2007 12:48 pm

Post » Wed Jun 20, 2012 9:16 am

Unless you're stashing equipable items, you don't need the loop(s) and you certainly don't need properties for individual items (FormList FTW!). Here's the code that does most of the sorting in my Bag of Holding mod:
akDonor.RemoveItem(akCurrentList, akDonor.GetItemCount(akCurrentList), True, akRecipient)

Should be a lot faster...
User avatar
Dina Boudreau
 
Posts: 3410
Joined: Thu Jan 04, 2007 10:59 pm

Post » Wed Jun 20, 2012 3:53 pm

You might find some optimization tips here:

http://www.gamesas.com/topic/1359724-on-the-run-time-of-skyrims-papyrus-scripts/
User avatar
Laura Richards
 
Posts: 3468
Joined: Mon Aug 28, 2006 4:42 am

Post » Wed Jun 20, 2012 3:27 pm

Well the answer is: Papyrus IS slow. It's a bytecode language, except for a few native functions.
User avatar
Lew.p
 
Posts: 3430
Joined: Thu Jun 07, 2007 5:31 pm

Post » Wed Jun 20, 2012 11:25 am

There are many other languages which compile to byte-code, that doesn't necessarily mean they are slow. That's lazy reasoning, sure there is additional work required to make the code actually execute, but this can (and has been) done very performant before, for references see .Net, Java or LuaJIT.

Bethesda had a design goal/requirement, how fast the VM had to be, and playing the game, it seems they meet that requirement.
User avatar
Matthew Barrows
 
Posts: 3388
Joined: Thu Jun 28, 2007 11:24 pm

Post » Wed Jun 20, 2012 8:09 am

There are many other languages which compile to byte-code, that doesn't necessarily mean they are slow. That's lazy reasoning, sure there is additional work required to make the code actually execute, but this can (and has been) done very performant before, for references see .Net, Java or LuaJIT.

Bethesda had a design goal/requirement, how fast the VM had to be, and playing the game, it seems they meet that requirement.

Not really "Lazy reasoning" it also comes from observation of the actual scripts running as well. Functions that would take on the order of 0.01 seconds in a native function call take 0.5-1 seconds in Papyrus.

Therefore, Papayrus is slow. This is why I've given up on trying to write my own function to convert from global rotations to local ones, since even if I DID make a function to compute them, each call would take 4 or 5 seconds to compute the correct X Y Z rotations from Roll Pitch and Yaw values.
User avatar
Rachel Eloise Getoutofmyface
 
Posts: 3445
Joined: Mon Oct 09, 2006 5:20 pm

Post » Wed Jun 20, 2012 7:54 am

You are still criticizing the VM not the language. Papyrus is a whole subsystem and it doesn't simply run your scripts it runs many of other scripts as well.
And of course any computational intensive work is done with a native language and then made accessible to the VM, that's how its done - the tradeoff between productivity and performance.
We should do the same, do computational intensive work with a SKSE plugin and call into that plugin with papyrus.
User avatar
Emily Graham
 
Posts: 3447
Joined: Sat Jul 22, 2006 11:34 am

Post » Wed Jun 20, 2012 3:51 pm

So you're saying that because we can use something that isn't papyrus, papyrus isn't slow?

Sorry, but your logic is flawed.
User avatar
Stacyia
 
Posts: 3361
Joined: Mon Jul 24, 2006 12:48 am

Post » Wed Jun 20, 2012 7:19 pm

Sigh, no. I am saying we should use the right tool for the job.
User avatar
Ryan Lutz
 
Posts: 3465
Joined: Sun Sep 09, 2007 12:39 pm

Post » Wed Jun 20, 2012 9:16 pm

Sigh, no. I am saying we should use the right tool for the job.

If it was a tool available with papyrus I would happily agree and let that comment slide. But the fact that if we want to do anything interesting with the "bold, new scripting system" means we have to use a tool that isn't even supported by the developers (SKSE), developed by smart people in their free time does not sit well with me.

They saw the scripts bogging down the game in previous titles so slapped on the time slicing and cut ties to the games main update logic and the scripts update logic even more, this means no synchonization with the game and the script unless the script runs under it's time budget, and it being mostly bytecode makes matters worse. There is no accomdation for this and it just limits the potential. Having to depend on something like SKSE to close this time-bound synchronization gap is frustrating. It should literally be part of papyrus, thats how important the script extenders are.

As an example, I have been working on something that relies on very simple operations, getting positions of in game objects and people. Typical scripts here run less than 1/2 a dozen lines of code, using mostly getters with minimal write operations. This still isn't fast enough in some cases because by the time the scripts complete 400+ frames pass and the data is simply out of date! This is a consequence of increasing performance, which I think it is a bit too much in some cases, SKSE or not.
User avatar
Vincent Joe
 
Posts: 3370
Joined: Wed Sep 26, 2007 1:13 pm

Post » Wed Jun 20, 2012 3:41 pm

Whether you like or not doesn't matter. Papyrus is just a tool and it accomplishes what it was set out to accomplish, and doing so with great simplicity.
If you want frame accurate data then clearly you need to be closer to the metal, native -- that can hardly be a surprise.
There is no hitbox-detection system in the game and papyrus was never meant to accommodate that feature, so you shouldn't be surprised if you have a hard time implementing one.

It's just a tool. And ya, you will have a hard time as long as you try to http://sisterschoice.typepad.com/sisters_choice_quilts/images/2008/02/03/square_peg_in_round_hole_2.jpg.
User avatar
Nicole Mark
 
Posts: 3384
Joined: Wed Apr 25, 2007 7:33 pm

Post » Wed Jun 20, 2012 6:11 am

If the existing native functions did their jobs properly, it wouldn't be such an issue. Until SetScale() properly adjusts the collision box of the object, I'm gonna complain.
User avatar
Chad Holloway
 
Posts: 3388
Joined: Wed Nov 21, 2007 5:21 am

Post » Wed Jun 20, 2012 9:50 am

Hehe, Stubbornness Achievement unlocked!

Your turn Bethesda :happy:
User avatar
Rachel Briere
 
Posts: 3438
Joined: Thu Dec 28, 2006 9:09 am

Post » Wed Jun 20, 2012 9:05 pm

Interesting observations by people. I'm impressed.

Xetrill, you're being a bit over the top I think, guarding Bethesda that much. This is a modable game, therefore you should take the side of the modders, lest future developmental games get even more nightmarish for modders to accomplish things. Based on your observations, I can only agree with 1 thing. I think Bethesda made sure that scripts meet certain requirements before they can be used in game, and this 'protects' innocent players from downloading mods filled with inane scripts by newbs, and possibly borking their save games..

I think this alone is good enough to justify the papyrus system. But for people who like to script decent mods and respect modding etiquette, we feel severely limited in being able to bring some good ideas in script implementation to the players in real time. I think in the end, mods with bad scripting code would not be downloaded very much.

Unless you're stashing equipable items, you don't need the loop(s) and you certainly don't need properties for individual items (FormList FTW!). Here's the code that does most of the sorting in my Bag of Holding mod:
akDonor.RemoveItem(akCurrentList, akDonor.GetItemCount(akCurrentList), True, akRecipient)

Should be a lot faster...

Anyways, yeah, I agree that code is very nice Justin. If I'm just trying to sort items in that way, it's sufficient. I need to use loops as far as I can tell, because I have to test each item against a loadout list. And this requires testing each item in a list before I let it through. So the player does not want to sort Healing potions, they won't be sorted. Not to mention the currently equipped armor and weapons and favorites the player already has hotkeyed dont get sorted every short visit to the player home. If you've got code for that. I'd be very, very happy!
User avatar
Erin S
 
Posts: 3416
Joined: Sat Jul 29, 2006 2:06 pm

Post » Wed Jun 20, 2012 4:18 pm

I'm over the top? Yeah, that happens :happy: but my point of view is from both sides, as a developer and as a modder. And well, Skyrim is a commercial product first, its developed on a budget which includes money and time. So anything that isn't needed by the core product is essentially a wasted effort. At least initially, later on that might shift, to direction that values modders requests more.

BTW, have you seen http://www.youtube.com/watch?v=7awkYKbKHik? I mean specifically the one week Bethesda gave their developers to do whatever they wanted, because with the last patch we saw some of that coming to the game. And as it looks this required potentially breaking changes (changing some record's structure) so I guess, Bethesda is stepping it up.

And as always, this is essential in development: Use the right tool for the job.
For example, an AI implementation isn't what papyrus is there for, but calling into that implementation could very well be, in which case papyrus becomes the glue.
User avatar
Rex Help
 
Posts: 3380
Joined: Mon Jun 18, 2007 6:52 pm

Post » Wed Jun 20, 2012 9:04 pm

malkion: Thanks :smile: It's fast too, even when moving a lot of items. Favorites, as far as I know, aren't currently checkable. For weapon stashing, something like...
	aiListIndex = (akCurrentList.GetSize() - 1)	While (aiListIndex > -1)		akCurrentForm = akCurrentList.GetAt(aiListIndex) As Weapon		If akDonor.IsEquipped(akCurrentForm) ; akDonor As Actor			If akDonor.GetEquippedWeapon() == akCurrentForm ; Right hand				If akDonor.GetEquippedWeapon(True) == akCurrentForm ; Left & right hand					akDonor.RemoveItem(akCurrentForm, akDonor.GetItemCount(akCurrentForm) - 2, True, akRecipient)				EndIf			ElseIf akDonor.GetEquippedWeapon(True) == akCurrentForm ; Left hand				akDonor.RemoveItem(akCurrentForm, akDonor.GetItemCount(akCurrentForm) - 1, True, akRecipient)			EndIf		Else			akDonor.RemoveItem(akCurrentForm, akDonor.GetItemCount(akCurrentForm), True, akRecipient)		EndIf		If Player.GetItemCount(akCurrentList)			aiListIndex -= 1		Else			aiListIndex = -1		EndIf	EndWhile
...should work (still working on it). That's a snippet from the same Sort() function that only fires if stashing weapons and it takes awhile, but doesn't remove equipped items. Apparel's easier 'cause there can be only one of any given item equipped.

Thought: 'While' loops seem to try to resolve themselves as quickly as possible. When my bag is sorting with a loop, it blinks in the inventory screen once per loop for some reason and, after overclocking my CPU, it's blinking noticeably faster as though there's no preset interval and the code will iterate as quickly as it can.
User avatar
Haley Merkley
 
Posts: 3356
Joined: Sat Jan 13, 2007 12:53 pm

Post » Wed Jun 20, 2012 6:42 am

Hmm, I'm trying to work it out by comparing the formlist being looped to another form list..

There is no elegant solution as far as I can tell. So I'll be resorting to a lot of behind the scenes scripting. Meaning, in the player's cell, the player will only see so many containers, but I will have to implement a lot of form lists and a lot of containers to sort things into, before removing all items into the house container.

Hehe, thank you papryrus. If only RemoveAllTypedItems from FONV, or something similar was available.
User avatar
Alessandra Botham
 
Posts: 3440
Joined: Mon Nov 13, 2006 6:27 pm

Post » Wed Jun 20, 2012 9:03 am

You can nest While loops in other While loops.
			While (aiListOfListsIndex > -1)				akCurrentList = BagOfHoldingSortWeaponsAllFLST.GetAt(aiListOfListsIndex) As FormList				If Player.GetItemCount(akCurrentList)					If Player.IsEquipped(akCurrentList)						aiListIndex = (akCurrentList.GetSize() - 1)						While (aiListIndex > -1)							akCurrentForm = akCurrentList.GetAt(aiListIndex) As Weapon							If Player.IsEquipped(akCurrentForm)								If Player.GetEquippedWeapon() == akCurrentForm									If Player.GetEquippedWeapon(True) == akCurrentForm										Player.RemoveItem(akCurrentForm, Player.GetItemCount(akCurrentForm) - 2, True, Self)									EndIf								ElseIf Player.GetEquippedWeapon(True) == akCurrentForm									Player.RemoveItem(akCurrentForm, Player.GetItemCount(akCurrentForm) - 1, True, Self)								EndIf							Else								Player.RemoveItem(akCurrentForm, Player.GetItemCount(akCurrentForm), True, Self)							EndIf							If Player.GetItemCount(akCurrentList)								aiListIndex -= 1							Else								aiListIndex = -1							EndIf						EndWhile						aiListOfListsIndex -= 1					Else						Player.RemoveItem(akCurrentList, Player.GetItemCount(akCurrentList), True, Self)						aiListOfListsIndex -= 1					EndIf				Else					aiListOfListsIndex -= 1				EndIf			EndWhile
The more FormLists in the FLST of FLSTs, the faster it completes. Even so, it still takes awhile. ={
User avatar
Sebrina Johnstone
 
Posts: 3456
Joined: Sat Jun 24, 2006 12:58 pm

Post » Wed Jun 20, 2012 6:14 am

ok Justin, you win. here's some code to demonstrate..

FormList Property List AutoFormList Property NoList AutoInt Index = 0While (Index < List.GetSize())If !NoList.HasForm(List.GetAt(Index))  Game.GetPlayer().RemoveItem(List.GetAt(Index), Game.GetPlayer().GetItemCount(List.GetAt(Index), True, Self)EndIfIndex += 1EndWhile

At this point in time, going back to the original post. The NoList is being populated with forms to not sort. And this executes very slow on very large formlists. Especially with a 'Sort Everything' master activator with 2763 armor items alone, weapon list, potion list, etc.. Heheh. Oh, I saw RealmEleven's idea. Not bad, I think he's making the player put items one by one into a container that gets transported to the destination container, using key words and filling in gaps with form lists. this certainly buys some time...
User avatar
carly mcdonough
 
Posts: 3402
Joined: Fri Jul 28, 2006 3:23 am

Post » Wed Jun 20, 2012 8:25 pm

I'm still looking for ways to expedite that part. Been meaning to test RemoveItem() to see if, say, the player has two of weapon X equipped and weapon X is in a FormList, if 'Player.RemoveItem(akCurrentList, Player.GetItemCount(akCurrentList) - 2, True, Self)' would leave weapon X in both hands, preferentially not moving equipped items. If so, that could shave a bunch of time and eliminate the need for the loops.

*experiments*

RemoveAllTypedItems from FONV: Perhaps SKSE could hook it up :smile:
2763: Dayum! That's one mondo FLST!
User avatar
Angus Poole
 
Posts: 3594
Joined: Fri Aug 03, 2007 9:04 pm

Post » Wed Jun 20, 2012 1:52 pm

The more FormLists in the FLST of FLSTs, the faster it completes. Even so, it still takes awhile. ={

We can have a Formlist of Formlists? Nice! I was so disappointed when I found that we couldn't have nested arrays.
User avatar
Laura
 
Posts: 3456
Joined: Sun Sep 10, 2006 7:11 am

Post » Wed Jun 20, 2012 12:31 pm

RemoveAllTypedItems has been requested, hopefully it will be in the first Papyrus http://www.gamesas.com/topic/1356343-wipz-skyrim-script-extender-skse/page__view__findpost__p__20481020 :)

@Justin, in the inner loop where at least one item has been found to be equipped, it will probably speed it up if you could filter out the equipped items from the full list and do a bulk RemoveItem() on most of the weapons on the list in one go. Even if you had to use an empty tempformlist just used for this purpose. It's probably the UI having to be updated (and blinking) that is causes most of the lag.

Watching this to see how 'intelligent' the removeItems is for equipped weapons. Fingers crossed it does leave equipped items in hand if poss.
With FNV I had to avoid all equipped/hotkeyed/worn stuff as it was pretty random.
User avatar
Joey Avelar
 
Posts: 3370
Joined: Sat Aug 11, 2007 11:11 am

Post » Wed Jun 20, 2012 7:33 pm

Justin, not sure if this helps, but couldn't you isolate the IsEquipped (weapon) form, then do a small loop just for that item and remove item either at one shot -1 (or -2) to see if it works, or use a
if !IsEquipped, then if count > than 1 or 2 (dual wield), remove by 1 until left with just 1 or 2?

not sure if I just made sense.. Sorry.
User avatar
Cheville Thompson
 
Posts: 3404
Joined: Sun Mar 25, 2007 2:33 pm

Next

Return to V - Skyrim