NativeHashMap

Hi!
I’ve seen some mentions of this collection, is it available already or will it come later? Cause I can use NativeArray but I can’t seem to find NativeHashMap and I could use it for my job code (which btw works really great so far, I love IJobParallelFor).

The NativeHashMap will be available as we open up the beta part of ECS.

We’re still finalising various bits and pieces so that you will have a better experience when you get access.

Great, thanks for the quick reply. I have one other kind of related problem I am trying to wrap my head around. I have a struct that has an array as a member. And I’d like to use it inside of the job code, but I get an error that the struct must be blittable. Do you know any smart way to make a struct with an array blittable? I know I won’t have more than 100 elements in it, so I’d be happy with making it fixed 100 element array or something like this. The only way I’ve found so far is pretty ugly (making a struct with 100 element and overriding indexer operator to fake being an array).

I’ll get back to you tomorrow with more.

In case anyone needs something similar: here’s my hundred element struct that pretends to be an array :wink:

3383351–265696–HundredElementStruct.cs (19.6 KB)

Out curiosity Martin, if we wanted to use a NativeArray of a struct, but the struct requires an array within it, would we need to wait for other Native container types coming with the ECS? The largest issue is that NativeArray isn’t blittable even if the ‘T’ type is blittable.

Example:

public struct TestingStruct {
    public NativeArray<byte> Bytes; //Alternatively byte[] failed as well
}

private struct JTest : IJob {
        public NativeArray<TestingStruct> Data;
        public void Execute() {}
}

You are basically asking what I’ve already asked in the same topic ;p

It was more in case it wasn’t exactly what you needed. My reading has been greatly impaired via playing around with Job Systems keeping me up every night. Also to be fair Martin did say “tomorrow” about a week ago :slight_smile:

Nested containers are currently not supported. Its not possible to validate safety for that.

But more importantly, they are generally a terrible idea for performance and C# jobs are all about performance.

You are right, I was talking about a different thing, I’ve just misunderstood your post.

@MartingGram - any update about an array inside a struct?

Did you already try experimenting with fixed buffers?

1 Like

I did not, thanks! I’ll try it tomorrow and I’ll see if it helps.

Hey. :smiley:

It is true that I have been hiding a bit. Joachim did reply with a very good answer and rule of thumb.

@Nozynski The suggestion you posted with encapsulating the elements inside a class and using indexers isn’t really going to help you performance wise. What you are looking for are as @superpig mentions fixed buffers and moving into unsafe land.

I would recommend a bit of patience for the new containers that are coming. There will also be a bunch of samples that can show case various access patterns with jobs and ECS.

1 Like

I would vote for new containers to be somewhat as elegant in design as Span if possible. I realize it’s very early, but really NativeArray needs to die in a fire at some point.

They do different things, though. Span doesn’t own its backing store.

1 Like

What’s confusing is how the underlying data is managed in relation to NativeArray itself. The allocation options make things even fuzzier. Does it really behave like a value type should? The strong implication is that it doesn’t just by looking at the api.

Span on the other hand is very clear and works as you would expect.

Naming is I think unfortunate but more of a minor issue. Is it a buffer or an array? doesn’t look like either to me really. If it’s really a value type then ‘Native’ just adds to the confusion.

Slicing a minor thing also, but why a separate type for that?

Here is our goals we had for native array and native containers

  • Zero GC allocation (60 or 90 FPS games need the ability to never ever allocate GC memory)
  • Safety in the editor with the most amazing error messages
    • Double dispose detection
    • Leak detection
    • Out of bounds checks
  • Race condition detectionAny race conditions are detected based on you declaring if you read or write to the NativeArrays. Both in terms of expressing dependencies but also reading from a nativeaarray after a job that writes to it has been scheduled. Essentially a combination of Runtime Checks + (Static analysis - upcoming not yet shipped) will provide 100% coverage of all race conditions.
  • Absolute best performance when deployed. All checks can be disabled and everything will work assuming you had no exceptions thrown by the safety system in the editor or in debug builds.
  • Control over memory allocators (Temp is cheaper than persistent memory as you would expect and avoids fragmentation)
  • Tight control over memory avoids any lock contention issues with the Garbage collector offering massive speedups

These are the requirements and they are all met.

As such it has to be a struct. Internally it contains a pointer to the data. Naturally one wants to have safety mechanism. This is where the editor job debugger / AtomicSafetyHandle comes in. All native containers can be copied around as if they are reference types. I agree it would be nice if it was a class but the above goals are more important than consistency with C#.

8 Likes

Span is a value type

To elaborate, what makes Span much simpler to reason about is that like NativeArray it’s an abstraction over memory, but it has a clear scope, it’s a value type and acts like one. I don’t have to think about the scope of the struct and the memory of the data it contains separately, nor reason about tmp vs non temp allocations or job vs non job scope. Or have to call dispose.