I would like to use struct to make sure that everything inside is copied by value, but I would like it to be flexible enough to carry different types. What kind of bad things, especially in terms of performance, may happen when using dynamic field in a struct?
public struct Group
{
public double A;
public double B;
public dynamic Data;
}
This struct is expected to contain information about a single element on the chart and will be used in a collection that on average will contain ~1000 and up to 100K elements.
IList<Group> bars = new List<Group>(1000)
Field Data in this struct is expected to contain various types
double
OHLC bar represented as 4 doubles
up or down arrow represented as 1 double and 1 bool
Is there a way to avoid using dynamic here and still represent data of different types in unified format? If not possible, what is the downside of using dynamic as a field type?
Couple of bad things that I can think of are casting, boxing, and use of cached delegates for different types. Is there anything worse?
Related
This question already has answers here:
Are slices passed by value?
(5 answers)
Closed 10 months ago.
I'm trying to make my code more performative saving memory if possible
I did some research but couldn't find anything about this specific case.
func createSlice() []int {
return s[]int{1,2,3}
}
func main() {
s2 := createSlice()
}
Would s2 be a completely new slice with its own underlying arrays or it would be a slice pointing to the underlying arrays of s?
You must know about the header of Go Slices. Then, you can have your answer yourself.
See what's in a slice header by checking out the reflect.SliceHeader type:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
Actually, Slice value is a header, containing the backing array along with the length and the capacity. It contains a pointer to the array of the elements are actually stored. The slice value does not contain the elements (unlike arrays).
So, when a slice is passed or returned, a copy will be passed or returned from this header along with the pointer. This pointer points to the same backed array. So, if you modify the elements of the slice, it modifies the backed array too and so all slices (those share the same backed array) also get the change.
So when you pass a slice to a function, a copy will be made from this header, including the pointer, which will point to the same backing array. Modifying the elements of the slice implies modifying the elements of the backing array, and so all slices which share the same backing array will "observe" the change.
See the blog https://blog.golang.org/go-slices-usage-and-internals.
Ref: Are golang slices passed by value?
I'm working with DNA data, in it's simplest form a name/id with sequence info:
public class FastaSequence {
private String name;
private String sequence;
{
The sequence is basically ATGGCTATCAC... for a few thousand chars long. I also have several hundred of these things to compare at any one time.
I need to be able to manipulate the chars in columns and cells, e.g. select the 125th char of each aligned sequence, in a GUI like JavaFX, so I was thinking to use TableView and convert the sequence to a list of chars and feed it to the table model as such. That way each char would get it's own column and I could like color all the T containing cells in red etc.
I have tried this with Python's TableView and I get a working prototype, but it's very slow to respond (loading a list, refreshing), even with a list of only a hundred sequences loaded. So my question is two-fold:
1) Will the JavaFX implementation be (a lot) faster than Python, even when loading a 100k or more cells?
2) Am I barking up the wrong tree and is there a better way to view/manipulate the data as I described it above? Should I be using another model?
UPDATE
I have been doing more research on this and found that the TableView in JavaFX is apparently not designed for huge numbers of columns: https://www.youtube.com/watch?v=udc2iRZBF0M at 1:51.
So I went back to testing a JTable in Swing. Without further fluff it gives me a responsive (i.e. easy to scroll) table upto about a 1000 lines of a 1000 chars. However, making the TableModel a little more complex and using custom cell renderers to center chars in the cell and remove cell borders and such destroys the responsiveness. Because of the many things I've tried I'm not posting all the code here. If/when I come closer to a solution I'll update with my minimal (working?) code. Maybe I need to go back a simpler control like a custom class based on a grid based layout, without the overhead of the JTable and it's model?
You can try something like this to make an array of all the characters in a string:
String sequence = "ATGGCTATCAC";
char[] chars = sequence.toCharArray();
And then you can use System.out.println(chars[125]); to print out the 125th char in that sequence.
I've never used tables in JavaFX before, but I think you can do something like this:
TableColumn column = new TableColumn("Letter");
table.getColumns().add(column);
root.getChildren.add(table);
ObservableList<Character> data = FXCollections.observableArrayList();
for (int i = 0; i < chars.length; i++) {
data.add(chars[i]);
}
table.setItems(data);
I have this API and I need to send some data to it as follows:
www.abc.com/orders/new?items[][id]=1001&items[][quantity]=2
So I have to pass in these arrays
items[][id]=1001
items[][quantity]=2
If there are multiple items, it should look like this
items[][id]=1001 & items[][quantity]=2
& items[][id]=1002 & items[][quantity]=3
So this is the problem I am having because I am aware that #Query can accept arrays but the arrangement needs to be element of ids first and then element of quantities. I cannot have all ids first and then quantities which is what happens.
#POST("/orders/new")
void send(#Query("items[][id]") String...ids, #Query("items[][quantity") String...quantity)
Please note I omitted the callback for simplicity.
I have also tried with lists, whereby the entire list contains all the needed information in the correct arrangement but then came the problem of only having a single #Query annotation i.e. "items[][id]" and "items[][quantity]"
Use #QueryMap. It is like a HashMap. From retrofit documentation, we have this:
For complex query parameter combinations a Map can be used.
#GET("/group/{id}/users")
List<User> groupList(#QueryMap Map<String, String> options);
So, in your case, the key of the map will be the id, and the value will be the quantity.
I have a navbar as a map:
var navbar = map[string]navbarTab{
}
Where navbarTab has various properties, child items and so on. When I try to render the navbar (with for tabKey := range navbar) it shows up in a random order. I'm aware range randomly sorts when it runs but there appears to be no way to get an ordered list of keys or iterate in the insertion order.
The playground link is here: http://play.golang.org/p/nSL1zhadg5 although it seems to not exhibit the same behavior.
How can I iterate over this map without breaking the insertion order?
The general concept of the map data structure is that it is a collection of key-value pairs. "Ordered" or "sorted" is nowhere mentioned.
Wikipedia definition:
In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears just once in the collection.
The map is one of the most useful data structures in computer science, so Go provides it as a built-in type. However, the language specification only specifies a general map (Map types):
A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type. The value of an uninitialized map is nil.
Note that the language specification not only leaves out the "ordered" or "sorted" words, it explicitly states the opposite: "unordered". But why? Because this gives greater freedom to the runtime to implement the map type. The language specification allows to use any map implementation like hash map, tree map etc. Note that the current (and previous) versions of Go use a hash map implementation, but you don't need to know that to use it.
The blog post Go maps in action is a must read regarding to this question.
Before Go 1, when a map was not changed, the runtime returned the keys in the same order when you iterated over its keys/entries multiple times. Note that this order could have changed if the map was modified as the implementation might needed to do a rehash to accommodate more entries. People started to rely on the same iteration order (when map was not changed), so starting with Go 1 the runtime randomizies map iteration order on purpose to get the attention of the developers that the order is not defined and can't be relied on.
What to do then?
If you need a sorted dataset (be it a collection of key-value pairs or anything else) either by insertion order or natural order defined by the key type or an arbitrary order, map is not the right choice. If you need a predefined order, slices (and arrays) are your friend. And if you need to be able to look up the elements by a predefined key, you may additionally build a map from the slice to allow fast look up of the elements by a key.
Either you build the map first and then a slice in proper order, or the slice first and then build a map from it is entirely up to you.
The aforementioned Go maps in action blog post has a section dedicated to Iteration order:
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Since Go 1 the runtime randomizes map iteration order, as programmers relied on the stable iteration order of the previous implementation. If you require a stable iteration order you must maintain a separate data structure that specifies that order. This example uses a separate sorted slice of keys to print a map[int]string in key order:
import "sort"
var m map[int]string
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
P.S.:
...although it seems to not exhibit the same behavior.
Seemingly you see the "same iteration order" on the Go Playground because the outputs of the applications/codes on the Go Playground are cached. Once a new, yet-unique code is executed, its output is saved as new. Once the same code is executed, the saved output is presented without running the code again. So basically it's not the same iteration order what you see, it's the exactly same output without executing any of the code again.
P.S. #2
Although using for range the iteration order is "random", there are notable exceptions in the standard lib that do process maps in sorted order, namely the encoding/json, text/template, html/template and fmt packages. For more details, see In Golang, why are iterations over maps random?
Go maps do not maintain the insertion order; you will have to implement this behavior yourself.
Example:
type NavigationMap struct {
m map[string]navbarTab
keys []string
}
func NewNavigationMap() *NavigationMap { ... }
func (n *NavigationMap) Set(k string, v navbarTab) {
n.m[k] = v
n.keys = append(n.keys, k)
}
This example is not complete and does not cover all use-cases (eg. updating insertion order on duplicate keys).
If your use-case includes re-inserting the same key multiple times (this will not update insertion order for key k if it was already in the map):
func (n *NavigationMap) Set(k string, v navbarTab) {
_, present := n.m[k]
n.m[k] = v
if !present {
n.keys = append(n.keys, k)
}
}
Choose the simplest thing that satisfies your requirements.
I have a JDOQL/DataNucleus storage layer which stores values that can have multiple primitive types in a varchar field. Some of them are numeric, and I need to compare (</>/...) them with numeric constants. How does one achieve that? I was trying to use e.g. (java.lang.)Long.parse on the field or value (e.g. java.lang.Long.parseLong(field) > java.lang.Long.parseLong(string_param)), supplying a parameter of type long against string field, etc. but it doesn't work. In fact, I very rarely get any errors, for various combinations it would return all values or no values for no easily discernible reasons.
Is there documentation for this?
Clarification: the field is of string type (actually a string collection from which I do a get). For some subset of values they may store ints, e.g. "3" string, and I need to do e.g. value >= 2 filters.
I tried using casts, but not much, they do produce errors, let me investigate some more
JDO has a well documented set of methods that are valid for use with JDOQL, upon which DataNucleus JDO adds some additional ones and allows users to add on support for others as per
http://www.datanucleus.org/products/accessplatform_3_3/jdo/jdoql.html#methods
then you also can use JDOQL casts (on the same page as that link).