Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
loinburger
Jul 10, 2004
Sweet Sauce Jones
I'm taking a similar approach, where when a batch manager's core worker becomes idle then it blocks indefinitely on a BlockingQueue#take call, I add a new worker to the AuxiliaryPool that polls the other batch managers' queues looking for work, and the new worker presumably reuses the idle core worker's thread (or not, that's up to the ThreadPoolExecutor). The reason I'm creating a new auxiliary worker rather than reusing the core worker to poll the other batch managers' queues is that a worker executing a job can't be interrupted (I'm looking for the Thread.interrupted() flag because this means that an admin wants to reboot the server, in which case the entire batch of jobs will be executed again on restart), a job's execution time can be arbitrarily long, and I want the system to be reasonably responsive. If BatchMangerA's workers are all idle and BatchMangerB is using up the entire auxiliary pool then a user might submit a small batch of short BatchManagerA jobs: currently BatchManagerA's workers will wake up, get some new threads from the thread pool, and immediately start on the batch; whereas if those workers were executing jobs for BatchManagerB then they'd be stuck until they finished their current jobs and I might be left with a frustrated user.

loinburger fucked around with this message at 22:37 on Oct 20, 2015

Adbot
ADBOT LOVES YOU

Squashy Nipples
Aug 18, 2007

Yet another newbie question:

I wrote a simple piece of code that iterates through the String[] args with a FOR loop:
code:
for (int i = 0; i < args.length; i++) {
But NetBeans barked at me and told me to use this format:
code:
for (String arg : args){
Is there a good reason for this, or is this merely convention?

The only thing I can think of is that the first code creates an unnecessary temp variable, which then has to be cleaned up by the garbage man.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Squashy Nipples posted:

Yet another newbie question:

I wrote a simple piece of code that iterates through the String[] args with a FOR loop:
code:
for (int i = 0; i < args.length; i++) {
But NetBeans barked at me and told me to use this format:
code:
for (String arg : args){
Is there a good reason for this, or is this merely convention?

The only thing I can think of is that the first code creates an unnecessary temp variable, which then has to be cleaned up by the garbage man.

It's generally more readable to use the foreach format, and less error prone since your don't forget which index variable goes to which array. That said, there are times that you need the actual index pointer (as a counter, etc) so foreach isn't always great. For example, if you need to know that this is the third argument, foreach won't give you that.

loinburger
Jul 10, 2004
Sweet Sauce Jones
The temp variable goes on the stack instead of on the heap, so cleanup is free.

The second one is preferred because your intent is clearer, and because the code applies to any sort of array or collection while the former only applies to arrays and indexed collections like ArrayList - it will take somebody reading your code slightly less time to figure out what the second loop is doing compared to the first loop, and (obviously this second bit doesn't apply here) it will be slightly easier to refactor your Array/ArrayList/Whatever into a non-indexed collection e.g. a Set if you've used the second type of loop.

Note that for something like an ArrayList the semantics of the first loop are different than the semantics of the second loop:
code:
public void fun(ArrayList<Object> arrayList) {
    for(int i = 0; i < arrayList.size(); i++) {
        if(somePredicate) {
            arrayList.add(new Object());
        }
        System.out.println(arrayList.get(i).toString());
    }

    for(Object o : arrayList) {
        if(somePredicate) {
             arrayList.add(new Object());
         }
         System.out.println(o.toString());
    }
}
The first loop will handle this fine (assuming that somePredicate isn't always true and the loop eventually terminates), the second will throw a ConcurrentModificationException. If a collection's iterator would throw a ConcurrentModificationException if you were looping through it and modified the underlying data structure in the loop / from a different thread / whatever (this is the case with most (all?) non-concurrent collections), then the for-each loop will throw a ConcurrentModificationException under the same circumstances.

Sistergodiva
Jan 3, 2006

I'm like you,
I have no shame.

Hello again! I think I need to set up a better system for my game entities, probably using inheritance. I realized that having different arrays for items and exits made it hard to prioritize when clicking on somewhere they overlap.

Would setting up a class called Entities and then creating subclasses for it (npc, exit, item, etc) be a good idea?

I was thinking something along the lines of loading all enteties and subclasses into an array, for looping through when you click to see if you click on any of them.

Maybe in the render loop I could have it iterate through the array and then drawing everything unless String entityImage = null.

Then I could have a pickup method on the item subclass, a transition method on the exit subclass, conversation method on the npc subclass, etc.

Does this seem feasible or what I totally missed something?

Making items picked up stay in the next available inventory slot was giving me some trouble, but I figure this way the item subclass could have a int for inventory-slot that get's set when you pick it up. As it is right now I move picked items to an arraylist to get them in the right order.

Squashy Nipples
Aug 18, 2007

Great answers, thanks guys!

I just did the trail on the StringBuilder Object. My tendency is to apply .toString() every time I need to represent the Object as String, but just for giggles I removed them all to see what happens. It appears that you don't always need to do it?

Sometimes Java can tell when it needs to convert it for you, and other times it throws an error. Is there a reason why you need to use it sometimes, but not others?

Zorro KingOfEngland
May 7, 2008

Many String-based methods in the core library that take an Object parameter will call .toString on the object before representing it. For example, System.out.println has an overload that takes an Object (as does StringBuilder). If you look at the source for the Object overload of println, you can see how that happens.

System.out.println:
http://grepcode.com/file/repository....lang.Object%29

StringBuilder.append
http://grepcode.com/file/repository....lang.Object%29

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Sistergodiva posted:

Hello again! I think I need to set up a better system for my game entities, probably using inheritance. I realized that having different arrays for items and exits made it hard to prioritize when clicking on somewhere they overlap.

Would setting up a class called Entities and then creating subclasses for it (npc, exit, item, etc) be a good idea?

I was thinking something along the lines of loading all enteties and subclasses into an array, for looping through when you click to see if you click on any of them.

Maybe in the render loop I could have it iterate through the array and then drawing everything unless String entityImage = null.

Then I could have a pickup method on the item subclass, a transition method on the exit subclass, conversation method on the npc subclass, etc.

Does this seem feasible or what I totally missed something?

Making items picked up stay in the next available inventory slot was giving me some trouble, but I figure this way the item subclass could have a int for inventory-slot that get's set when you pick it up. As it is right now I move picked items to an arraylist to get them in the right order.

You might want to look at interfaces instead of inheritance - an interface is basically where you define a set of method signatures, so if your class implements that interface, it has to provide those methods. That way you can have a bunch of completely different classes, but your code can treat them all as Entity types (if that's what you call your interface) by calling those Entity methods

It's a bit like a car and a house both having the ability to unlock() a door with a key and enter() the thing. They're completely different objects, even the doors and keys are different, but there's that common functionality you expect from both, so you can treat them as implementing an UnlockableEntrance interface or something

Anyway point is sometimes it makes more sense to tack on an interface API when you want to give several types some common functionality, rather than forcing them to inherit from the same, single superclass. Other people will probably have better advice about choosing when to do one or the other, especially since these days you can actually implement code in the interface itself, but you should decide if your Entities have enough in common that they should descend from a central type, or if they would be better having a few methods in common that they can handle internally

Uhh as for your checking code, you're basically polling everything and asking if they're 'here' when someone clicks a coordinate, right? That's a naive approach (as in, it doesn't try to be clever about limiting its checking) which is fine for occasional clicks with a handful of items. If you have a ton of items, or complex checking code for each, or you're doing it at 60fps, it could end up needing optimisation, like a data structure that holds objects in a particular area so you can limit your queries. It's up to you and what you're doing! Definitely nothing wrong with a simple approach if it works for what you're doing

Having an array of everything sounds like it might be useful for iterating over, yeah - you can still use lists though! Arrays are good for fixed stuff you rarely change, or things where indexing is important (e.g. your inventory slots). Lists are good for stuff that changes. There's a tradeoff - like with your drawables, you're talking about iterating over every object and asking it if it has a drawable. You have to do this on every frame. Or you could create a list of stuffToDraw, that only contains the things that need rendering, and bam - just iterate over that knowing that you need to draw all its contents. You do the polling work once - and you can add and remove from this easily, or change the order of elements if you want

And don't forget you don't need to actually move stuff from one list (or array) to another - your objects can be in multiple collections if that makes sense to you, like a door can be in a list of exits and a list of visible items. You just need to make sure you're consistent about adding and removing things

Ugh megapost

Volguus
Mar 3, 2009
Interfaces vs Inheritance (abstract classes or otherwise), always the fun part.
When designing something and having to choose between a certain concept to be an interface or an abstract class there are some rules of thumb to keep in mind:

- Interfaces usually describe behaviour (Serializable) or capability (Cloneable) . Interfaces DO NOT have state. Do not have data members. Any methods that the interface declares have to be implemented by the actual objects.
- Abstract classes have state, they have data members and can and do provide implementations for methods.

That's the simplest rule to think of. You will have state? You're an abstract class. You describe behaviour or operations or services and have no state? You're an interface.

Easy peasy ...

Carbon dioxide
Oct 9, 2012

Volguus posted:

Interfaces vs Inheritance (abstract classes or otherwise), always the fun part.
When designing something and having to choose between a certain concept to be an interface or an abstract class there are some rules of thumb to keep in mind:

- Interfaces usually describe behaviour (Serializable) or capability (Cloneable) . Interfaces DO NOT have state. Do not have data members. Any methods that the interface declares have to be implemented by the actual objects.
- Abstract classes have state, they have data members and can and do provide implementations for methods.

That's the simplest rule to think of. You will have state? You're an abstract class. You describe behaviour or operations or services and have no state? You're an interface.

Easy peasy ...

You say that, but the other day I was looking at someone else's code and they had an interface that didn't declare any methods. All it did was define some constants. I showed that to some others just to see their terrified look.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Carbon dioxide posted:

You say that, but the other day I was looking at someone else's code and they had an interface that didn't declare any methods. All it did was define some constants. I showed that to some others just to see their terrified look.

It's not necessarily that bad.

https://en.m.wikipedia.org/wiki/Marker_interface_pattern

Mind you, annotations have mostly taken over for this on Java.

Squashy Nipples
Aug 18, 2007

Ok, I need some help with variables. I'm trying to structure my simple Black Jack game better, so I decided that the main part should come out of the WHILE loop, and be it's own chunk of code.

However, once I pull it out of the main code, I no longer have access to the variables?
It won't let me make them PUBLIC, so the only way I could make it work was to make it into a method to return a value that represents the results of the hand played.

code:
package PlayingCards;

import java.util.Scanner;

public class BlackJack {
    
    public static void main(String[] args) {
    
    //Version 1:
        //new deck for every hand
        //dealer must hit on 16 or less (no hitting on "soft 17" )
        //no splits, doubling down, or insurance
        //fixed bet amount ($50)
        //Starting pool set at $250
        
        final int bet = 50;
        final int startWad = 250;
        int wad = startWad;
        
        char response;
        boolean contLoop = true;
        
        Scanner scanner = new Scanner(System.in);

        System.out.format("Your starting total is: $%,d%n", wad);
        
        while (contLoop) {
    
            wad = wad + PlayAHandOfBlackJack();
       
            //check for BUST
            if (wad <=0) {
                System.out.println("You busted! Nothing left to bet, better luck next time.");
                System.out.println("Thank you for playing! Goodbye.");
                return;
            }
            
            //Display wad, ask if they want to continue
            System.out.format("Your total cash is: $%,d%n", wad); 
            System.out.println(); 
            System.out.println("Do you wish to play another hand? (Y/N)"); 
            if (scanner.next().toLowerCase().charAt(0) != 'y') { 
                contLoop = false;
            }
        }
        //branch based on winnings
        if (wad == startWad) {
            System.out.println("You didn't win any money, but at least you broke even.");
        } else if  (wad > startWad) {   
            System.out.format("Congratulations! You won $%,d%n", (wad-startWad));
        } else {
            System.out.format("Sorry! You lost $%,d%n", (startWad-wad));
        }
        System.out.println("Thank you for playing! Goodbye.");
    }
    
    public static int PlayAHandOfBlackJack(){
    //return value is how much the player won/lost
        int winnings = 0;
        //do stuff
        return winnings;
    }
}
For example, "scanner" and "wad" are not available to my method!
It's all in the same class, why can't I use them in other subroutines within the class?

Squashy Nipples fucked around with this message at 23:20 on Oct 24, 2015

Kuule hain nussivan
Nov 27, 2008

Squashy Nipples posted:

For example, "scanner" and "wad" are not available to my method!
It's all in the same class, why can't I use them in other subroutines within the class?
To access them within the same class, you need to declare them as class variables. These go directly under the class declaration so...

code:
public class BlackJack {
    Scanner scanner;
    int wad;

Squashy Nipples
Aug 18, 2007

Uggggg! There isn't a DUH big enough for that.

Thanks, I'll get the hang of these curly braces sooner or later.


EDIT: Ya know, that's one thing that I really appreciate about Java: the concepts that I struggle with the most tend to make a lot of sense once I understand why.

Squashy Nipples fucked around with this message at 00:10 on Oct 25, 2015

Kuule hain nussivan
Nov 27, 2008

Squashy Nipples posted:

Uggggg! There isn't a DUH big enough for that.

Thanks, I'll get the hang of these curly braces sooner or later.


EDIT: Ya know, that's one thing that I really appreciate about Java: the concepts that I struggle with the most tend to make a lot of sense once I understand why.
No worries, glad I can be of help to someone. I still ponder whether to declare stuff as class variables or send it to a method as a parameter all the time. Especially when dealing with GUI stuff.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Don't forget that you're running in a static method, not an instance method, so you can't just casually reference those variables as you're not an instance of the class. You'll need to make them static, or move your code into an instance method, make an instance if your class, and call that method.

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.

Kuule hain nussivan posted:

No worries, glad I can be of help to someone. I still ponder whether to declare stuff as class variables or send it to a method as a parameter all the time. Especially when dealing with GUI stuff.

I subscribe to the "as little shared state as possible" philosophy. If you're passing method variables around, there's less opportunity for a multithreading bug to work its way into your code, since there's no way for two different threads to access the same value at the same time. If you declare your variables as final, they're easier to reason about. That being said, if you can declare a class variable as final (it's available at construction time, and you never re-assign it), it's generally going to be just as safe to have it as a class variable as it is to pass it around.

loinburger
Jul 10, 2004
Sweet Sauce Jones
In addition to making variables final, use immutable collections where you can

Squashy Nipples
Aug 18, 2007

Kuule hain nussivan posted:

No worries, glad I can be of help to someone. I still ponder whether to declare stuff as class variables or send it to a method as a parameter all the time. Especially when dealing with GUI stuff.

Yup, often an issue in my other programming as well... there are times to explicitly pass variables, and times to widen a scope, but usually it's a judgement call as to which is better. Now, variables are passed by reference, correct? So instead of making "wad" a Class variable, I could just pass it to the Method, and make changes to it directly there, right?


As for making them Class variables, there is one part that I still don't understand:

In order to put the Class variables up top (outside of the "main" block), NetBeans required that I add the "Static" keyword. Why? That's the top-level, there is nothing else that could call that code, so there can't possibly be any other instances of it running. It's like... the Head Vampire.


Volmarias posted:

Don't forget that you're running in a static method, not an instance method, so you can't just casually reference those variables as you're not an instance of the class. You'll need to make them static, or move your code into an instance method, make an instance if your class, and call that method.

In order to make it an Instance Method, I would just have to make it "private NON-static" like this, right:

code:
    private int PlayAHandOfBlackJack(){
    //return value is how much the player won/lost
        int winnings = 0;
        //do stuff
        return winnings;
    }

Squashy Nipples
Aug 18, 2007

One more thing:

In my Black Jack game, as an improvement to my Card Class, I added a Method called "toStringShort".

It uses the Unicode symbols for the suits to provide a short String respresentation for a given Card Object.
https://en.wikipedia.org/wiki/Playing_cards_in_Unicode

For example, instead of:
"Ace of Hearts"
"Seven of Spades"

You get:
"A[Unicode symbol for a Heart]" ( '\u2665' )
"7[Unicode symbol for a Spade]" ( '\u2660' )

This works great in NetBean's output window, but when I pack up the Jar and run it from the command line, I get question marks instead:
A?
7?

Is there something I missed that I was supposed to include in my Jar? Or does the Windows command line just not support Unicode characters?

Squashy Nipples fucked around with this message at 02:47 on Oct 26, 2015

loinburger
Jul 10, 2004
Sweet Sauce Jones
Stackoverflow says to change the cmd font to Lucida Console (right-click the title bar, go to properties, change font), and then type in "chcp 65001" to change to UTF-8

Squashy Nipples
Aug 18, 2007

Ok, that will work for the short term.

I guess long term the answer is to build GUI and use real graphics to depict the cards.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Squashy Nipples posted:

In order to put the Class variables up top (outside of the "main" block), NetBeans required that I add the "Static" keyword. Why? That's the top-level, there is nothing else that could call that code, so there can't possibly be any other instances of it running. It's like... the Head Vampire.

You have only static methods. If you're refactoring a variable to be class scoped, it will also be static.


quote:

In order to make it an Instance Method, I would just have to make it "private NON-static" like this, right:

code:
    private int PlayAHandOfBlackJack(){
    //return value is how much the player won/lost
        int winnings = 0;
        //do stuff
        return winnings;
    }

Yes, although now you have to have an instance of your class to call that method on.

TheresaJayne
Jul 1, 2011

Squashy Nipples posted:

Yet another newbie question:

I wrote a simple piece of code that iterates through the String[] args with a FOR loop:
code:
for (int i = 0; i < args.length; i++) {
But NetBeans barked at me and told me to use this format:
code:
for (String arg : args){
Is there a good reason for this, or is this merely convention?

The only thing I can think of is that the first code creates an unnecessary temp variable, which then has to be cleaned up by the garbage man.

its just best practice coding standards either will work, the one suggested by netbeans is more streamlined. If you had used the variable i then it would not have suggested it.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

It's worth pointing out that the index version is 'cleaner' because it doesn't have to create an Iterator object. Not generally a problem, but if you're doing this regularly (say in a render loop) with resource constraints, you might end up allocating a lot of garbage objects very quickly. The index version's a bit faster too, if you need the performance. Otherwise go with the concise and easy version. S'nice

Squashy Nipples
Aug 18, 2007

loinburger posted:

Stackoverflow says to change the cmd font to Lucida Console (right-click the title bar, go to properties, change font), and then type in "chcp 65001" to change to UTF-8

Just can't get this to work; no matter what I change, I still get question marks.
Did a lot of my own Googling, too.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

baka kaba posted:

It's worth pointing out that the index version is 'cleaner' because it doesn't have to create an Iterator object. Not generally a problem, but if you're doing this regularly (say in a render loop) with resource constraints, you might end up allocating a lot of garbage objects very quickly. The index version's a bit faster too, if you need the performance. Otherwise go with the concise and easy version. S'nice

Something something premature optimization something maintenance costs vs performance costs something something

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Volmarias posted:

Something something premature optimization something maintenance costs vs performance costs something something

I did it on Android because my memory use was creeping up on a draw list in a render loop! Just saying that there are sometimes situations where you might care about these things, but in general don't bother and go with the nice easy readable version

No Safe Word
Feb 26, 2005

baka kaba posted:

I did it on Android because my memory use was creeping up on a draw list in a render loop! Just saying that there are sometimes situations where you might care about these things, but in general don't bother and go with the nice easy readable version

Yes but don't confuse "more performant in some scenarios" with "cleaner". The foreach style loop is pretty much objectively "cleaner" from a code standpoint.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

No Safe Word posted:

Yes but don't confuse "more performant in some scenarios" with "cleaner". The foreach style loop is pretty much objectively "cleaner" from a code standpoint.

I meant cleaner in terms of garbage, fewer temporary allocations

MrPablo
Mar 21, 2003

baka kaba posted:

I meant cleaner in terms of garbage, fewer temporary allocations

There are no additional allocations when using an iterator versus using an index:

code:
> cat Test.java 

public class Test {
  public static void main(String args[]) {
    System.out.format("%s: %d%n", "test_index", test_index(args));
    System.out.format("%s: %d%n", "test_iterator", test_iterator(args));
  }

  public static int test_index(final String args[]) {
    int r = 0;

    for (int i = 0, l = args.length; i < l; i++)
      r += args[i].length();

    return r;
  }

  public static int test_iterator(final String args[]) {
    int r = 0;

    for (String arg: args)
      r += arg.length();

    return r;
  }
};
code:
> javap -c Test
// main() disassembly omitted for brevity

public static int test_index(java.lang.String[]);
  Code:
   0:	iconst_0
   1:	istore_1
   2:	iconst_0
   3:	istore_2
   4:	aload_0
   5:	arraylength
   6:	istore_3
   7:	iload_2
   8:	iload_3
   9:	if_icmpge	27
   12:	iload_1
   13:	aload_0
   14:	iload_2
   15:	aaload
   16:	invokevirtual	#11; //Method java/lang/String.length:()I
   19:	iadd
   20:	istore_1
   21:	iinc	2, 1
   24:	goto	7
   27:	iload_1
   28:	ireturn

public static int test_iterator(java.lang.String[]);
  Code:
   0:	iconst_0
   1:	istore_1
   2:	aload_0
   3:	astore_2
   4:	aload_2
   5:	arraylength
   6:	istore_3
   7:	iconst_0
   8:	istore	4
   10:	iload	4
   12:	iload_3
   13:	if_icmpge	36
   16:	aload_2
   17:	iload	4
   19:	aaload
   20:	astore	5
   22:	iload_1
   23:	aload	5
   25:	invokevirtual	#11; //Method java/lang/String.length:()I
   28:	iadd
   29:	istore_1
   30:	iinc	4, 1
   33:	goto	10
   36:	iload_1
   37:	ireturn
Technically test_index() has has slightly fewer instructions than test_iterator(), but the difference will probably not result in any tangible performance difference because it will be dwarfed by the actual work in the loop body.

The only real justification for using an index over an iterator is because you need the index for some other calculation.

MrPablo fucked around with this message at 21:38 on Oct 26, 2015

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Is there actually an iterator in there, since it's a plain array? I know the initial question was about an array but I was thinking about using foreach generally - like my issue was with a List, and every frame it created a new Iterator with the foreach call

MrPablo
Mar 21, 2003

baka kaba posted:

Is there actually an iterator in there, since it's a plain array? I know the initial question was about an array but I was thinking about using foreach generally - like my issue was with a List, and every frame it created a new Iterator with the foreach call

Yes, iterating over a List allocates an Iterator (or, rather, allocates an instance that implements Iterator):

code:
import java.util.List;
import java.util.ArrayList;

public class Test {
  public static void main(String args[]) {
    // build list
    List<String> list = new ArrayList<String>();
    for (String arg: args)
      list.add(arg);

    System.out.format("%s: %d%n", "test_list_index", test_list_index(list));
    System.out.format("%s: %d%n", "test_list_iterator", test_list_iterator(list));
  }

  public static int test_list_index(final List<String> list) {
    int r = 0;

    for (int i = 0, l = list.size(); i < l; i++)
      r += list.get(i).length();

    return r;
  }

  public static int test_list_iterator(final List<String> list) {
    int r = 0;

    for (String arg: list)
      r += arg.length();

    return r;
  }
};
code:
> javap -c Test
// main() dump omitted for brevity

public static int test_list_index(java.util.List);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iconst_0
   3:   istore_2
   4:   aload_0
   5:   invokeinterface #14,  1; //InterfaceMethod java/util/List.size:()I
   10:  istore_3
   11:  iload_2
   12:  iload_3
   13:  if_icmpge       38
   16:  iload_1
   17:  aload_0
   18:  iload_2
   19:  invokeinterface #15,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
   24:  checkcast       #16; //class java/lang/String
   27:  invokevirtual   #17; //Method java/lang/String.length:()I
   30:  iadd
   31:  istore_1
   32:  iinc    2, 1
   35:  goto    11
   38:  iload_1
   39:  ireturn

public static int test_list_iterator(java.util.List);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   aload_0
   3:   invokeinterface #18,  1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
   8:   astore_2
   9:   aload_2
   10:  invokeinterface #19,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   15:  ifeq    38
   18:  aload_2
   19:  invokeinterface #20,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   24:  checkcast       #16; //class java/lang/String
   27:  astore_3
   28:  iload_1
   29:  aload_3
   30:  invokevirtual   #17; //Method java/lang/String.length:()I
   33:  iadd
   34:  istore_1
   35:  goto    9
   38:  iload_1
   39:  ireturn
In this case it would be better to use the index version when GC churn is an issue (for example, a loop that is called every frame in a game).

The catch is that the run time of get() is implementation-dependent:

quote:

The List interface provides four methods for positional (indexed) access to list elements. Lists (like Java arrays) are zero based. Note that these operations may execute in time proportional to the index value for some implementations (the LinkedList class, for example). Thus, iterating over the elements in a list is typically preferable to indexing through it if the caller does not know the implementation.

Edit: Replaced my wording with quote from official documentation.

MrPablo fucked around with this message at 01:12 on Oct 27, 2015

Sedro
Dec 31, 2008
Java has a marker interface RandomAccess for this purpose

quote:

As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:
Java code:
     for (int i=0, n=list.size(); i < n; i++)
         list.get(i);

runs faster than this loop:
Java code:
     for (Iterator i=list.iterator(); i.hasNext(); )
         i.next();

MrPablo
Mar 21, 2003

Sedro posted:

Java has a marker interface RandomAccess for this purpose

Cool, thanks :).

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Thanks for the info! But yeah I definitely wasn't trying to encourage premature optimisation - more saying that foreach is pretty much the default, but there are a few cases where janitoring indices is what you have to do

Jo
Jan 24, 2005

:allears:
Soiled Meat
I have a random generator from which I'm extracting random numbers in an anonymous function. It seems like doing this is producing strange results and more duplicates than I'd expect. Is it okay to use random in async operations and lambdas?

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Jo posted:

I have a random generator from which I'm extracting random numbers in an anonymous function. It seems like doing this is producing strange results and more duplicates than I'd expect. Is it okay to use random in async operations and lambdas?

Are you initializing a new random object each time? If so that's bad, and you're going to get strange results. If its a lambda you probably are.
I guess you'll need like a static class to hold the random reference? Well, Math.random() should do that already, if you're using that instead of a manual Random object.

No idea about thread safety of random so somebody else can probably weigh in more.

Jo
Jan 24, 2005

:allears:
Soiled Meat

Zaphod42 posted:

Are you initializing a new random object each time? If so that's bad, and you're going to get strange results. If its a lambda you probably are.
I guess you'll need like a static class to hold the random reference? Well, Math.random() should do that already, if you're using that instead of a manual Random object.

No idea about thread safety of random so somebody else can probably weigh in more.

This is with respect to line 39 of this file: https://github.com/JosephCatrambone/Aij/blob/master/src/main/java/com/josephcatrambone/aij/trainers/RBMTrainer.java

I'm initializing Random random = new Random() when the class is created. When I use it in `Arrays.parallelSetAll(sampleIndices, x -> random.nextInt(inputs.numRows()));` poo poo gets fucky. I saw the same when I was writing another function using random in a lambda. It's entirely plausible that another factor is masking this and the issue is presenting in a way that makes me want to blame random.

Adbot
ADBOT LOVES YOU

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Jo posted:

This is with respect to line 39 of this file: https://github.com/JosephCatrambone/Aij/blob/master/src/main/java/com/josephcatrambone/aij/trainers/RBMTrainer.java

I'm initializing Random random = new Random() when the class is created. When I use it in `Arrays.parallelSetAll(sampleIndices, x -> random.nextInt(inputs.numRows()));` poo poo gets fucky. I saw the same when I was writing another function using random in a lambda. It's entirely plausible that another factor is masking this and the issue is presenting in a way that makes me want to blame random.

Hm, I'm not exactly sure how the lambda handles the condition but its likely calling it from all the delegate threads at the same time, leading to the unusual behavior.

You could try using a ThreadLocalRandom instead, or otherwise creating a new Random for each lambda. Ideally you'd use the same generator but using different generators with different seeds should be okay too? How random does it need to be exactly?

Quick googling says that Random should be thread safe in practice though so I'm not sure.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply