I didn't perform any actual benchmarking on this, but looking at the engine's source code, it's easy to make a few assumptions explaining this with both function call overhead as well as memory usage. If we look at the first few lines of the implementation for get_image()
, we'll see that the generated/passed image data is a (grayscale) image using 1 byte per pixel:
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
Vector<uint8_t> data;
data.resize(p_width * p_height);
uint8_t *wd8 = data.ptrw();
Doing the simple multiplication (and ignoring extra overhead from classes/references), this means we'll be working with roughly 1 MB of data allocated in one go (this is oversimplification here, though). To actually fill the data, the C++ part will call the very same get_noise_2d()
function a million times, too. However, the GDScript side will never see those 1 MB, only the reference (4 or 8 bytes based on architecture).
Now if you go with the million calls from GDScript you should expect a difference, even from memory alone, ignoring extra overhead from calling. get_noise_2d()
returns a float
. While the size of this datatype might change between implementations/platforms etc. you can generally assume that it's nowadays at least 32 bits (or 4 bytes) long. This means we're passing 4 bytes per "pixel" resulting in 4 MB of data.
So data wise – only talking about the information moving between the raw C++ part and the script runtime – we're looking at a factor of 1 million (4 MB vs. 4 byte). As such, having an actual factor of around 2 isn't that bad overall (mostly thanks to fast memory these days I guess).
But besides that, this totally sounds like a typical case of "you're (probably) doing it wrong". If you're trying to generate a huge or nearly infinite terrain, you should definitely split it up into individual "chunks", generating them on the fly and only while needed (e.g. close to the player). This will significantly reduce generation time, lower overall memory usage and improve your framerate, too.
If this doesn't apply to you and you're trying to do something else, I'm still sticking with "you're (probably) doing it wrong", but we'd need a few more details.