Performance issues

i dont want to say say it but, snap is dissapointigly slow. its like every time i really start to get somewhere in a project it gets so laggy its basically useless. im sure theres plenty of optimizations that i could be making but ive been spending alot of time trying to redo what ive already done, and im starting to think its just snaps limitations.

for example, this scrolling tile base project i made awhile back; Scratch, runs without a problem, but Snap even after some touch ups its unusable.

same thing with my text editor project, Scratch runs lightning fast Snap ccant see straight after a couple lines;

i may be missing something i could be doing to counter this, im open for suggestions.

I think it is your internet.

Certain things Snap! does quicker than Scratch, other things not.

The Scratch team have heavily optimised Scratch for speed for "game" type projects because that's what Scratchers are usually creating - Snap! has other priorities.

EarthRuler's suggestion is very much probably NOT the cause :slight_smile:

then how would i notice that the scratch projects run smoothly lol

Wow. Nice project! But you gotta watch out what you compare. When I look at your Scratch code there are hardly any abstractions in there, all is written out and even copied verbatim a lot. Such code looks ugly but runs fast. On the other hand if I look at this block of yours:

it's clear why your Snap! code is slow, especially since you're constantly calling this block 4 times in a row! What's the idea behind this architecture even? Why are you defining a "test" variable and assign it a new (!) ring every time the block gets invoked? Of course that's terribly inefficient. You're not doing the same in Scratch are you?

As a very quick experiment I turned your temporary "test" variable into a regular reporter block, and voilà, your (really neat!) game was running about as fast in Snap! as it does in Scratch:

https://snap.berkeley.edu/snap/snap.html#present:Username=jens&ProjectName=tile%20scrolling

And that's just one thing that I immediately noticed, I'm sure there are more such slow-downs to be found in your game.

Were did you get this horrible idea to define a subroutine as a temporary ring inside another block definition that uses it?

haha that's what I call 'its almost time for work and I still haven't figured this out yet' code. it's not uncommon I just end up throwing pieces together just to see what happens, especially when I'm getting frustrated. I mustve done something right because that block wasn't originally part of the code and I didn't even realize I saved it in that state but yet somehow you've found sense in my ridiculous test variable set up and (im assuming) solved my problem. I'll have to check it out when I get home tn from work but I'm pretty intrigued to see what you've done.

and also I used that snapinator thing to convert the project, that's why there's so much repetition and bulky code, scratch doesn't let you define reporters and is real tight with their lists. that is actually what I was comparing, is the project in the same structure as it was in scratch, runs significantly slower. im hoping your workaround (which you may not have even suggested if not for my terrible check corners block ;​) works and is usable, guess I'll see when I get home. thanks.

edit: im not sure what youre seeing but im not noticing much of a difference in speed. i guess ill have to keep trying to find optimizations

I do this when the subroutine is only of use in the block definition and that block needs to call to it from multiple places. It seems wrong to clutter up a project by making the helper function into a globally accessible block.

This used to be common practice in Lisp back when I learned it.

sure, it's fine to do that in the interest of abstraction, but then don't complain about "performance issues" :slight_smile:

Remember that the anonymous function is created new every time you call the block (because it's assigned to a temporary variable), rather than just once when you define it as a permanent block. This makes it very inefficient in situations that rely on rapid successions of running the block inside an animation loop.

I think there's a classic teachable moment here about the tradeoff between expressive elegance and execution efficiency. Expressive abstraction is wonderful, because it dramatically speeds up development turnaround. You get much more done in a shorter time. Or, as my favorite LISP song says "God had a deadline, so he wrote it all in Lisp" (Eternal Flame - GNU Project - Free Software Foundation).

Code that runs fast is often full of optimizations that are hard to understand, repetitive, and terrible to maintain. To make something run fast the secret is to literally make it "do less". Often that involves more code that ends up doing less than elegant code. For example, using a variable to remember the result of a function, so you can just reuse what you've already computed before instead of calling the function again is the secret of all caching. This gets to be very complicated very quickly, because you're introducing state to what used to be "pure", and you'll need to write more code that figures out when to invalidate the cache. Suddenly there are a lot more places where things can (and will!) go wrong, that have side effects you didn't consider and bugs that have nothing to do with the feature you're working on. And - worst of all - you'll have all the mathematician hotshots snickering at your oafish, clumsy code. But when it's all working it'll be super fast, albeit very hard for others and your later self to build upon.

Hardcore "game" devs will likewise snicker at the highlevel programming languages, claiming that their allegedly "simple" imperative ones are much more efficient and "faster" than those highfalutin' scripting ones. Their code will be full of things like a giant "game loop" in which they'll explicitly poll for the state of individual keys instead of listening to events. They'll use lots of global variables to cache state that different parts of what looks like spaghetti code all access, and you're going to have a hard time dissecting where in code which feature is defined, because it'll all be intermingled into one big mesh.

This is, btw, one of the reasons why I'm not all that convinced that "making games" is the ultimate motivational activity for budding programmers anymore. Making good games that are fun to play almost always encourages, if not requires, a specialized programming style geared towards less abstraction and special-cased optimizations. But I'm digressing...

++1 :slight_smile:

..........

There are thousands of popular games that are exceptions to this. Yes, games with million dollar plus budgets put lots of effort on efficiency at the price of clarity but consider for example

There are many very popular "causal games".

And I think there is trend towards optimizing compilers and just-in-time compilation that works best on clean code.

That's interesting Ken. Do you know the source of any such popular games? I'd be really interested in how compilers optimize things. I have myself talked to quite a few serious game developers, and also to developers of gaming frameworks, and the "game loop" was the predominant architecture in each and everyone of them. It literally stands in the way of abstraction.

Regarding compiler optimization it is a huge field with hundreds of techniques. See

I used to go to the Game Developer Conferences and even in the late 90s and early 2000s there was a split between those who used high-level languages and those who used C and assembler. And those who make engines like the Unreal Engine which provides a relatively clean interface/framework upon which lots of class A games are built. But I haven't kept up to really learn how things have changed.

Many years ago I did research on partial evaluation which can transform very inefficient functional programs into much more efficient ones. I made an illustration of this in Snap!

jens, my issue is with the tile mapping method (algorithm?) i use frequently in projects. in scratch I would originally use clones but with 16x16 tiles that exceeded the clone limit to fill the screen. so to work around this I instead would iterate through the rows : columns (clear screen; for y in screen_height{ for x in screen_width{ go to x, y; set costume; stamp}} ) . this has always worked surprisingly quick for me even with larger amounts of tiles. but in snap I can't seem to get this screen scanning method to work without slowing down significantly. I've tried with clones too and I can't tell if it's any faster. maybe you have a recommendation for a different approach to map the tiles more efficiently? this isn't exclusively meant to be a game base, there's lots of applications for a mapping tiles to a grid. a bitmap editor for example, or a digital logic simulator, or just a visual, editable representation of a matrix. point is I like and use this method and really hope to find a way to implement it in snap without digging through and piecing together javascript canvas commands which i know are more than capable of doing the trick but that's a pretty far stretch to solve what I imagine shouldn't be that big of a problem. I'll keep looking and trying things but my point stands that scratch does this tile mapping technique very smoothly but snap struggles to keep up when using the same technique. if you're not convinced I will make two identical projects on each and show you the difference. but this is something I run into time and time again

I usually make my own C-shaped GRID block, customized to the parameters I want to use. Lately I love using the COMBINATIONS reporter for it:

Then I use it to render information stored in a table:

Here's a little demo project you can explore.

Does that method work for you?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.