I want to write a function that can accept arrays of fixed length, but different arrays have different lengths.
I know that i can pass the slice with arr[:] (the function will accept []T), but is there another way, maybe more efficient?
I'm using a struct that i'd like to mantain with fixed length arrays (for documentation purposes), so using slices everywhere at declaration time is not optimal for my purpose.
No there is no way to pass different size arrays, because the length of an array is part of the type.
For example [3]int is a different type then [2]int.
At all in Go it is not recommended to use arrays you should use slices (https://golang.org/doc/effective_go.html#arrays).
Related
I'm implementing an algorithm that checks nodes in a mesh for a certain value. To store information on which node I have already checked I'd like to use an unordered_map with the pointer to the node as a key. I can then simply use umap.find(pointer) to see if the node was already checked and skip it. This way I can accomplish it in O(n) time.
However I don't need to actually store a value for the map. The key itself is enough information. Is std::unordered_map even the right solution then? If so, what should I put for the "value" field maximize performace? I have a 32bit embedded system, so I thought of just putting uint32_t or uint_fast32_t there.
tl;dr:
Is std::unordered_map the right tool to store keys without values?
Will the native hash function work well for pointers? Or would you suggest a different hashin algorithm?
What do I put as "value" for the map if using std::unordered_map to optimize for performance?
Is std::unordered_map the right tool to store keys without values?
I would use a std::unordered_set in these situations.
Will the native hash function work well for pointers?
Yes. It is most likely just a cast from pointer to std::size_t.
What do I put as "value" for the map if using std::unordered_map to optimize for performance?
If you use a std::unordered_set instead, there is no value, only the pointers.
Is std::unordered_map the right tool to store keys without values?
No - std::unordered_set is the one to use when you don't have distinct keys and values.
Will the native hash function work well for pointers? Or would you suggest a different hashin algorithm?
The "native" compiler-supplied hash function probably casts the pointer value to size_t - a kind of identity hash. That may or may not work well depending on the compromises your Standard Library has chosen. GCC and clang use prime numbers of buckets in the hash table, so it will work fine. Visual C++ (and many non-Standard hash table implementations) use powers of two (i.e. 128, 256, 512...). Powers of two are used because it's very fast to map them on to buckets - just AND with a bitwise mask (127, 255, 511) to retain however-many less-significant bits you need. The problem with doing that with pointers is that often the pointed-to objects have some alignment, so they may all be multiples of e.g. 4 or 8. A multiple of 8 always has the three least significant bits set to 0: those bits don't contribute to the randomised placement of the value in a bucket. Instead, only every 8th bucket will receive any share of the elements being hashed. If you have an implementation like this, then you're probably better off using a better hash function. At the least, you could say bit-shift the pointer values right by enough to remove the known zeros.
What do I put as "value" for the map if using std::unordered_map to optimize for performance?
Again, you should use an std::unordered_set, so don't have to worry about a value.
I have two instances of this struct with references inside (as properties):
type ST struct {
some *float64
createdAt *time.Time
}
How can I preform a check for equality for two different instances of this struct? Is it only by using reflect?
While you could use reflection, as Corey Ogburn suggested, I would not do so for a simple struct like that. Per the official Go Blog, reflection is
a powerful tool that should be used with care and avoided unless strictly necessary
-- The Laws of Reflection
It should be a simple exercise for you to write a function that takes two pointers to values of your struct type and returns a boolean true/false as to whether they are equal, first by testing for nil pointers and then by testing for equality of each of the fields of the struct.
time.Time values already have an equality test method with signature
func (t Time) Equal(u Time) bool
Depending on your use cases, the bigger problem may be comparing two floating point values for equality. While == comparisons work on float64 values, for many applications you want two float values to be considered equal when they are close, as well as when they are exactly the same. If that is the case for your application, I recommend defining an equal function that accepts a precision and verifies that the difference between the two values is not greater than the precision. To learn more, research floating point representations of decimal values.
Note that time package documentation has this to say about using pointers:
Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time.
So you should probably change the type of createdAt in your struct.
You can use reflect.DeepEqual.
DeepEqual reports whether x and y are “deeply equal,” defined as follows. Two values of identical type are deeply equal if one of the following cases applies. Values of distinct types are never deeply equal.
The documentation then goes on to describe how arrays, structs, functions, pointers and other types are considered to be deeply equal.
I have to convert double value array into stream
What is difference between following two approach? Which one is better ?
double [] dArray = {1.2,2.3,3.4,4.5};
Stream<double[]> usingStream = Stream.of(dArray); //approach 1
DoubleStream usingArrays = Arrays.stream(dArray); //approach 2
Obviously, Stream.of(dArray) gives you a Stream<double[]> whose single element is the input array, which is probably not what you want. You could use that approach if your input was a Double[] instead of a primitive array, since then you would have gotten a Stream<Double> of the elements of the array.
Therefore Arrays.stream(dArray) is the way to go when you need to transform an array of doubles to a stream of doubles.
Besides the fact that they are different?
DoubleStream can be thought as Stream<Double> (but as a primitive), while Stream<double[]> is a Stream of arrays.
Stream.of and Arrays.stream are entirely different things for different purposes and hence should not be compared.
Stream.of when passed a single dimensional array as in your example will yield a stream with a single element being the array itself which in majority of the cases is not what you want.
Arrays.stream, well as name suggests operates on arrays, whereas Stream.of is more general.
It would have been better and more entertaining had you asked what’s the difference between DoubleStream.of(dArray) and Arrays.stream(dArray).
I need to use large maps with large strings as keys. Is there a way in go's default map to specify the comparison test so that the key is treated as an address? If not, are there good libraries that implement this?
Note that what I want to prevent is long strings constantly being passed by copy whenever a map lookup is made.
For the particular case of strings, Go does what you want by default: strings are currently represented by pointer/length pairs so you're not copying string data around when you copy strings.
In general, you can't specify a custom comparison (or hash) function. Other types and custom structs are treated according to rules listed in the spec: pointers are compared by address, for example, fixed-size arrays are compared by value, and slice types aren't comparable in general so struct types that include them aren't usable as map key types.
I want to know, how to make a single dimensional array with unknown number of elements.
For example:
Name: array[1..x] of Integer;
where x is an integer the user enters later in the program.
Declare your array as dynamic, see documentation. You can use SetLength to set its length at runtime, and Length to get the number of elements.
You can't. If you want to make a dinamic link between variables, you need to use Lists. Here is an example of how to make this.