Skip to main content
added 53 characters in body
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123

No.

seperate the tileset image into a bunch of different Image objects

It wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter formatdrawImage() to reference intorefer to one single part of the Image's heap allocation, to recall each sub-image, then modify it, then copy back.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always beA good engineer is always very specific in yourtheir communication with yourselfthemselves -- for clarity of thought -- and with others. Choose your words wisely.

No.

seperate the tileset image into a bunch of different Image objects

It wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the Image's heap allocation, to recall each sub-image, then modify it, then copy back.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

No.

seperate the tileset image into a bunch of different Image objects

It wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter drawImage() to refer to one single part of the Image's heap allocation to recall each sub-image, then modify it, then copy back.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. A good engineer is always very specific in their communication with themselves -- for clarity of thought -- and with others. Choose your words wisely.

deleted 479 characters in body
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123

No.

seperate the tileset image into a bunch of different Image objects

It almost certainly wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the Image's heap allocation, to recall each sub-image, then modify it.

But it is impossible to be sure without testing first, as this depends on your memory access pattern, e.g. how many times you access the atlas directly after pulling it into cache, as the cost to pull data into cache from the heap is high... it has to be worth the effort. I assume you are willing to pay the price to have editable tiles, at least during production; you can later remove "tile edit" code for the released version of your game if performance needs to be 100%then copy back.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

seperate the tileset image into a bunch of different Image objects

It almost certainly wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the heap, to recall each sub-image, then modify it.

But it is impossible to be sure without testing first, as this depends on your memory access pattern, e.g. how many times you access the atlas directly after pulling it into cache, as the cost to pull data into cache from the heap is high... it has to be worth the effort. I assume you are willing to pay the price to have editable tiles, at least during production; you can later remove "tile edit" code for the released version of your game if performance needs to be 100%.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

No.

seperate the tileset image into a bunch of different Image objects

It wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the Image's heap allocation, to recall each sub-image, then modify it, then copy back.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

deleted 5 characters in body
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123

seperate the tileset image into a bunch of different Image objects

It almost certainly wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); else you'd induce more cache missesinduce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the heap, to recall each sub-image. Locality of reference is ideal, then modify it.

But it is impossible to be sure without testing first, as this depends on your memory access pattern, e.g. how many times you access the atlas directly after pulling it into cache! Remember that, as the cost to pull data into cache from the heap is high, so... it has to be worth the effort. I assume you are willing to pay the price to have editable tiles, at least during production; you can later remove this"tile edit" code for the released version of your game if performance needs to be 100%.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method that Javascript allowsalone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

seperate the tileset image into a bunch of different Image objects

It almost certainly wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); else you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the heap, to recall each sub-image. Locality of reference is ideal.

But it is impossible to be sure without testing first, as this depends on your memory access pattern, e.g. how many times you access the atlas directly after pulling it into cache! Remember that the cost to pull data into cache from the heap is high, so it has to be worth the effort. I assume you are willing to pay the price to have editable tiles, at least during production; you can later remove this code for the released version of your game if performance needs to be 100%.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method that Javascript allows for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

seperate the tileset image into a bunch of different Image objects

It almost certainly wouldn't be faster to create a slew of separate Images: each of these would be a copy existing on a different part of the heap (memory); you'd induce more cache misses by scattering multiple image copies across the heap. Better to use the 9-parameter format to reference into one single part of the heap, to recall each sub-image, then modify it.

But it is impossible to be sure without testing first, as this depends on your memory access pattern, e.g. how many times you access the atlas directly after pulling it into cache, as the cost to pull data into cache from the heap is high... it has to be worth the effort. I assume you are willing to pay the price to have editable tiles, at least during production; you can later remove "tile edit" code for the released version of your game if performance needs to be 100%.

however, I may decide to change the map at runtime

Image is based on an ImageData reference which itself is based on its data property, which is a Uint8ClampedArray. This buffer can be fast-set using set:

image.data.set(subImage, startOffset);

If you want to fast-modify, you can copy out part of this Uint8ClampedArray, modify it, and write it back again using subarray:

const subimage = image.data.subarray(startOffset, endOffset); //note: creates a new buffer

//...modify copied subimage here... 

image.data.set(subImage, startOffset); //set back into the atlas

This is the fastest method Javascript alone (without WASM) offers for image manipulation, to date. For modifying the subimage pixel by pixel, see this question for tips on fastest pixelwise writes.

better ... faster

These are two different things, nearly always, when it comes to code. You need to decide which you want. If you mean "easier for the programmer" then by all means split into multiple Images. If you mean faster, definitely do not do that. The Engineering Triangle is a salient reminder of the trade-offs we make. Always be specific in your communication with yourself and with others.

added 191 characters in body
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123
Loading
added 95 characters in body
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123
Loading
Source Link
Engineer
  • 30.3k
  • 4
  • 75
  • 123
Loading