Performance leak in my program (JavaScript)

Click For Summary

Discussion Overview

The discussion revolves around performance issues in a JavaScript-based snake game, specifically focusing on a perceived slowdown as the game progresses. Participants explore potential causes, debugging strategies, and algorithmic improvements related to the game's mechanics and performance.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • Some participants inquire whether the slowdown occurs at slower speeds or when the game is idle, suggesting the need for debugging with browser tools.
  • One participant notes that the slowdown may be due to the increasing number of operations required as the snake grows, particularly in checking for collisions and moving segments.
  • Another participant suggests simplifying the movement logic by only moving the last segment to the new head position, which could improve performance.
  • There is a discussion about whether a function is necessary to check if the snake's head collides with its body, with differing opinions on the need for a loop versus a more efficient data structure.
  • Some participants express uncertainty about the game's mechanics, such as how it ends and whether the snake can collide with itself.
  • One participant mentions that the performance issues may not be a memory leak but rather a limitation of JavaScript's handling of rapid repositioning of segments.
  • A suggestion is made to implement an auto-navigate feature for debugging purposes to isolate the slowdown issue.

Areas of Agreement / Disagreement

Participants express multiple competing views regarding the causes of the performance issues, the necessity of certain functions and loops, and the overall game mechanics. The discussion remains unresolved with no consensus on the best approach to address the slowdown.

Contextual Notes

Participants mention various assumptions about the game's mechanics and performance characteristics, but these are not fully explored or resolved. There are references to potential optimizations and alternative approaches that remain untested.

Who May Find This Useful

Developers interested in game programming, performance optimization in JavaScript, and algorithm design may find the insights and suggestions in this discussion relevant.

Jamin2112
Messages
973
Reaction score
12
Any ideas much appreciated.

Repro steps:
  • Open this: http://jaminweb.com/projs/snakegame.php
  • Change the speed to Fast
  • Go get a couple pieces of food, lengthening your snake a few blocks
  • Notice how it's already moving slower
Code:

https://github.com/jamkin/snake-game/blob/master/projs/snakegame.php
 
Last edited by a moderator:
Technology news on Phys.org
If the speed is slow does the game still slow down?

If you start the game and don't touch anything or mouse over it does it still slow down?

Have you used the browser debugger to see what's going on?

Can you characterize the slow down, does it smoothly slow down or slow and then speed up...?

You're either not releasing some memory or your list of snake segments list is growing and it's taking longer to process or you're making and releasing so many objects that garbage collection can't keep up.
 
One other point, I'm using an iPad and there's no arrow keys to press so you might need to consider tablets in your design.
 
Neat game.I was able to get to 130 at FAST before I saw it slow down. Not sure any normal humans could get much higher before their finger tendons burst into flame.

It may not be a memory leak per se, it may simply be that repositioning 13 snake segments in less than 100ms (the delay on FAST setting) exceeds JS's ability.

Not sure what ends a game other than hitting a wall. Sometimes games just seemed to end for no reason when I was nowhere near a wall. If I had to guess, can a game end if the snake drives into itself?

On my laptop, I often lost games by accidentally scrolling the play area off-screen. It would be helpful if the whole page fit on-screen during play. But this is a tidy-up thing. you've got bigger fish to fry.
 
Last edited:
Try this for debugging.

Make the snake auto-navigate, so that it never hits a wall (easy to do, in your hitWall function, just change endGame to changeDirection).
Oh, and give it, like 10 segments to start off.

Now let it run continuously. You'll be able tell if the slowdown is reproducible.
Start increasing the speed. (reducing the delay toward zero).
 
Are you sure the slow isn't because of Leibowitz hypothesis ?
 
As the snake grows, it does progressively more on each cycle of motion: it check whether the head hits its body, looping through all the body segments, and it moves every segment. I suspect it is the second operation that affects performance most significantly. You could measure its raw performance to be sure.

I should also remark that this second operation can be much simplified. You do not need to move all the segments. You only need to take the last segment and move it to the new location of the head. Things get a bit more complicated when the snake hits the food, because then it needs to grow; I leave figuring this out as an exercise.

You could also eliminate the "hit body" loop. Then the performance of motion will be wholly independent of the snake's length.
 
  • Like
Likes   Reactions: mafagafo
voko said:
I should also remark that this second operation can be much simplified. You do not need to move all the segments. You only need to take the last segment and move it to the new location of the head.

Oh, my gosh ... How did I not think of that?

Things get a bit more complicated when the snake hits the food, because then it needs to grow; I leave figuring this out as an exercise.

I have it working. Is there an obvious way of improving the algorithm?

You could also eliminate the "hit body" loop. Then the performance of motion will be wholly independent of the snake's length.

Isn't it essential to have a function to determine whether the snake's head hit its body? That's supposed to end the game.
 
DaveC426913 said:
It may not be a memory leak per se, it may simply be that repositioning 13 snake segments in less than 100ms (the delay on FAST setting) exceeds JS's ability.

That seems strange based on my previous experience with JS. I've made made very computationally expensive programs that worked lightning. The repositioning of 13 snake segments is only 100-200 operations or so.

Not sure what ends a game other than hitting a wall. Sometimes games just seemed to end for no reason when I was nowhere near a wall. If I had to guess, can a game end if the snake drives into itself?

Yes, according to the rules of the Snake arcade game, the snake cannot run into itself.

Interestingly, I just tried out someone else's implementation and there's slows down as well: http://patorjk.com/games/snake/
 
  • #10
Jamin2112 said:
Isn't it essential to have a function to determine whether the snake's head hit its body?

A function, yes.

A loop, not necessarily.
 
  • #11
voko said:
A function, yes.

A loop, not necessarily.

When the food gets placed in a new position (at a random place on the grid ... Later I'm going to optimize this by keeping a list of coordinates that the snake is not on, so that I can I add the food at a random one of those coordinates), I need to check whether that new position is on the snake, which requires looping through all its links -- no?
 
  • #12
Jamin2112 said:
I need to check whether that new position is on the snake, which requires looping through all its links -- no?

As I said, not necessarily. You need a data structure that gives you a yes/no answer without looping.
 
  • #13
I like the front end quite a bit.
 

Similar threads

  • · Replies 13 ·
Replies
13
Views
4K
  • · Replies 6 ·
Replies
6
Views
4K
  • · Replies 2 ·
Replies
2
Views
11K
  • · Replies 4 ·
Replies
4
Views
4K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 25 ·
Replies
25
Views
8K
  • · Replies 27 ·
Replies
27
Views
6K
  • · Replies 80 ·
3
Replies
80
Views
69K