Hi I am writing an arraylist in storage using
private void addItemToRecentListStorage1(Hashtable h){
Storage s1 = Storage.getInstance();
ArrayList<Hashtable> a = (ArrayList<Hashtable>)s1.readObject("RecentItems");
...
...
a.add(0,h);//adding on top
s1.writeObject("RecentItems", a);
}
If I inspect s1 immediately after adding 1st element, it shows me appropriately in storage hierarchy.
But at a time of adding 2nd element(HashTable) it clear the 1st stored hashtable values, though it shows as a blank element.
Means, I am getting 1 element(HashTable) in arraylist by readObject() but that hashtable's all 4 elements are wiped out. This was working earlier but now its wiping out HashTable data from arraylist.
So eachtime I am getting number of element incremented by 1 when I add element. But all previous hashtables' values are cleared.
Same thing is happening in emulator as well as device.
Check out if you have an exception in the console that might have been triggered by serialization failing for some of the objects within the array.
Related
I have used this HashMap for a few days now and no problems at all. Now I get an error about FloatingDecimal,parseDouble, ReadWrite, FileReadWrite, and Looping error.
the last thing I did to the program was adding $%.2f.formant to my ducts.second element it ran a few times I left to eat and came back to this!
I was able to narrow it down to when it pulls the data from the file and converts it to the hashmap setting.
Data in the file example 111,shoes,59.00
val fileName = "src/products.txt"
var products = HashMap<Int, Pair<String, Double>>()
var inputFD =File(fileName).forEachLine {
var pieces = it.split(",")
// println(pieces)
products [pieces [0].toInt()] = Pair(pieces [1].trim(),pieces[2].toDouble())
}
The data type in the file was altered when reading back in causing the whole program to crash. I wanted my double to be example 9.99 and when I read the file back in I added a $ sign meant for the front in view only. When the program was looking for a double (9.99) is only had the option of ($9.99) causing the error.
A large amount of data (+-15 000 records) is loaded via AJAX which is then used to populate two arrays, one sorted by ID the other by a name. Both the arrays contains the same objects just ordered differently.
The data is displayed in a tree view but the hierarchy can be changed by the user. The tree is virtualised on the first level so only the records displayed + 50% is 'materialized' as vue components.
Supplying both of the arrays as data to a vue instance is very slow. I suspect vue.js is adding observers to the objects twice, or change notifications is sent multiple times, I don't really know.
So only one of the arrays is added to vue the other is used out of band.
Vue slows down the addition of elements to an array a lot. If the array is populated before it is bound to the vue instance it takes +-20s before the tree view is displayed. If I bind it before populating the arrays it takes about +-50s before the tree view becomes usable (the elements are displayed almost instantly). This could be because of notifications going for all these elements added.
Is there a way to add a second array with duplicate data so vue.js watches it for changes, but it doesn't slow vue down as much?
Is there a way to switch watching/notifications of temporarily so elements could be added to an array without the penalty, yet be 'watched' when notifications is switched back on?
I'm not sure that my reasoning behind the slowdowns is correct, so maybe my questions are misguided.
O another thing I need the arrays to be watched and only one of the properties of the elements.
var recordsById = [];
var recordsByName = [];
// addRecord gets called for every record AJAX returns, so +-15 000
// calling addRecord 15 000 times before 'binding' takes 20 sec (20 sec with no display)
// calling addRecord after 'binding' takes > 50 sec (instant display but CPU usage makes treeview unausable)
function addRecord(record) {
var pos = binarySearch(recordsById, record);
recordsById.splice(0, pos, record);
pos = binarySearch(recordsByName, record);
recordsByName.splice(0, pos, record);
}
var treeView = new Vue({
el: '#treeView',
data: {
// If I uncomment following line, vue becomes very slow, not just for initial loading, but as a whole
//recordsById: recordsById,
recordsByName: recordsByName
},
computed: {
virtualizedList: function() {.....}
}
})
There are a couple techniques which might improve your performance.
Using the keys
For rendering large lists, the first thing you want to do is use a key. A great candidate for this is the id you speak about.
Use pagination
An obvious solution to "displaying a lot of data is slow" is "display less data". Let's face it, 15 000 is a lot. Even if Vue itself could insert and update so many rows quickly, think of the user's browser: will it be able to keep up? Even if it was the simplest possible list of text nodes, it would still be a lot of nodes.
Use virtual scrolling technique
If you don't like the look of pagination, a more advanced approach would be virtual scrolling. As user browses this large list, dynamically add the elements below, and remove the ones that the user has already seen. You keep the total number of elements from the list at the DOM at once to minimum.
I am trying to remove all the controls that are contained in my winform panel but they simply do not want to get removed - some of them are removed and some of them not. I have tried 2 approaches already and nothing:
foreach
foreach (Control controlEntry in this.contentsPanel.Controls)
{
this.contentsPanel.Controls.Remove(controlEntry);
}
for
for (int i = 0; i < this.contentsPanel.Controls.Count; i++)
{
this.contentsPanel.Controls.RemoveAt(i);
}
Why is this happening ?
You have to watch out for code like this, removing controls from their container like this produces an unrecoverable resource leak. Controls.Remove/At(), or the Controls.Clear() method as suggested by other posters, removes the control from the collection and re-hosts it to the "parking window". An otherwise invisible window where the native window can find a hospitable home without having to be destroyed. Ready to be re-hosted on another parent.
Which is the trap, you typically don't move it to another parent. The control will continue to survive on the parking window, consuming native Windows resources. The garbage collector cannot recover these resources. Eventually your program will crash when Windows refuses to provide more windows to your process. The exception message will say "Error creating handle".
Instead, you must dispose the control. Which also automatically removes the control from its parent. The proper code is:
while (contentsPanel.Controls.Count > 0) contentsPanel.Controls[0].Dispose();
Or iterate backwards if you find this a bit too bizarre looking.
Each time you remove control from collection, the collection changes. When you remove 1st element of Controls, 2nd element becomes 1st, so when you proceed to delete 2nd control, you are in fact removing 3rd element from original collection (skipping 2nd element).
If you want to remove all controls contained in collection, use this.contentsPanel.Controls.Clear(). If you want to remove controls by their indices in ControlCollection, first select controls to remove to separate list or array and then remove them.
If you want to remove them all then just do
this.contentsPanel.Controls.Clear()
The foreach will fail because you are changing the collection, which breaks the iterator.
The for fails because you are only removing every other item; consider: i=0, you remove the zeroth item. Now the item that was item 1 is item 0 - so when you remove item 1 (next loop iteration) you have jumped one.
Short version: use Clear():
contentsPanel.Controls.Clear();
Longer version: iterate backwards:
for(int i=contentsPanel.Controls.Count-1; i>=0;i--) {
contentsPanel.Controls.RemoveAt(i);
}
The first (Clear) is simpler.
I have a basic implementation of Conway's game of life written in elm running at uminokirin.com.
The source is visible here.
The program let users adjust the size of the toroïdal grid, click on cells to change their status, and randomize the world. It works well for small values (less than 50) on my computer.
However when attempting to use the randomize grid function on bigger grids (the threshold value doesn't seem to be always the same), the program becomes unresponsive without any warning and the only way to recover is to reload the app.
There is zero optimization in the GOL algorithm and using a single svg rectangle for every cell is probably horribly inefficient, but it sill doesn't explain why the program behaves in this way instead of say, slowing down.
Is this the elm runtime giving up? Or some kind of browser safeguard?
More importantly is there a way to prevent this behavior other than arbitrarily capping the maximum size of the grid?
The behavior you are observing is due to a Javascript stack overflow. After pressing the "randomize" button, in the browser console you can see the message "Uncaught RangeError: Maximum call stack size exceeded"
This happens because the randomize function allocates several large temporary variables. In particular, the shuffle function (which is called from the randomize function) appears to allocate two temporary lists that each have one element for every cell in the life grid. Elm may be smart about releasing these on a timely basis but this appears to push it too far.
To fix this you can use a simpler randomize function. The version shown below uses Elm Generators to generate a single list of Dead/Alive values and then initializes the randomized array from that list.
randomize2 : Array Cell -> Int -> Int -> Int -> Array Cell
randomize2 grid gs sd n =
let floatGen = Random.float 0.0 1.0
lifeGen = Random.map (\b -> if (b < toFloat n/100) then Alive else Dead) floatGen
listGen = Random.list (gs*gs) lifeGen
in fst (Random.step listGen (initialSeed sd)) |> fromList
Using this randomize function I was able to resize the grid up to 600x600 and randomize successfully. At that point I stopped testing.
How do I find the middle element of an ArrayList? What if the size is even or odd?
It turns out that a proper ArrayList object (in Java) maintains its size as a property of the object, so a call to arrayList.size() just accesses an internal integer. Easy.
/**
* Returns the number of elements in this list.
*
* #return the number of elements in this list
*/
public int size() {
return size;
}
It is both the shortest (in terms of characters) and fastest (in terms of execution speed) method available.
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.0size
So, presuming you want the "middle" element (i.e. item 3 in a list of 5 items -- 2 items on either side), it'd be this:
Object item = arrayList.get((arrayList.size()/2)+1);
Now, it gets a little trickier if you are thinking about an even sized array, because an exact middle doesn't exist. In an array of 4 elements, you have one item on one side, and two on the other.
If you accept that the "middle" will be biased to ward the end of the array, the above logic also works. Otherwise, you'll have to detect when the size of the elements is even and behave accordingly. Wind up your propeller beanie friends...
Object item = arrayList.get((arrayList.size()/2) + (arrayList.size() % 2));
if the arraylist is odd : list.get(list.size() / 2);
if the arratlist is even: list.get((list.size() / 2) -1);
If you have a limitation for not using arraylist.size() / arraylist.length() method; you can use two iterators. One of them iterates from beginning to the end of the array, the other iterates from end to the beginning. When they reach the same index on the arraylist, then you find the middle element.
Some additional controls might be necessary to assure iterators wait each other before next iteration, you should not miss the meeting point..etc.
While iterating, for both iterators you keep total number of elements they read. So they should iterate one element in a cycle. With cycle, I mean a process including these operations:
iteratorA reads one element from the beginning
iteratorB reads one element from the end
The iterators might need to read more than one index to read an element. In other words you should skip one element in one cycle, not one index.