Problem/Bug Common mistakes thread in plugin developmemt extremely outdated

Discussion in 'Bukkit Help' started by RcExtract, Jun 11, 2018.

Thread Status:
Not open for further replies.
  1. Offline

    timtower Moderator Moderator

    @RcExtract The UUID is for name change support based from Mojang, not a Bukkit thing here.
  2. Offline


    Im not talking about the creation of this method. Im talking about the recommendation of this method to resolve player memory leak issue.
  3. Offline


    Yes, Bukkit is based on Java, but knowing Java is a prerequisite for programming Bukkit plugins. This forum is for helping people learn Bukkit. Learning Java (at least the fundamentals) is supposed to be done elsewhere.

    I don't know about you, but I don't always consider myself knowing better than the people who write the API. If there is a perfectly serviceable API method, then I don't see why you would go out of your way to use WeakReferences.
  4. Offline


    list two options then. Each one has its own advantages.
  5. Offline


    Well, I have said that there are downsides to WeakReferences, so I will not agree with you. But seeing as you're not bringing any new arguments to the table, any further discussion is just pointless.

    I suppose we'll have to let @timtower decide what should be written in the thread.
  6. Offline



    I suggest to list both player referencing solutions. If you disagree, i will give up and focus on adding more common mistakes.

    I have some additional tips:

    Try to avoid autoboxing and autounboxing. For example, use Boolean.TRUE and Boolean.FALSE for Boolean, and true and false for boolean. For small numbers, the wrapper of the primitive number is cached so there will no performance effects. For larger numbers, boxing or unboxing is done. This will slightly increase performance, and its a good practice.

    Array.asList does not work for primitive types.

    Use Collections.singletonList instead of Arrays.asList if you plan the list to only have 1 element.

    Minimise Collection.toArray calls. They copy arrays and are expensive.

    Minimize jdbc calls. For example, a single INSERT statement can insert a max of 1000 rows. If you like, use addBatch and executeBatch for executing multiple statements. Use preparedstatement for calling a single pattern of statement multiple times with custom parameters. The PreparedStatement.setString, setInt, setNull, etc. Directly sends the arguments in their own type to SQL server, which is different from Statement, because Statement requires you to convert arguments to String.

    When you override equals method, be sure to override hashCode method. You can calculate hashcode for your type easily with Objects.hash(Object[]). Of course you can have your own hashing algorithm.

    Use LinkedList instead of ArrayList if you plan to add a lot of elements in the middle of the list.
    Last edited: Sep 24, 2018
  7. Offline

    timtower Moderator Moderator

    @RcExtract And in how far do those apply to starting developers?
    Most don't know the Boolean as far as I know.
    Performance is a small thing in software that has a build in sleep and fixed tickrate anyways.
    This has no explanation about why.
    About the jdbc: how the hell do you get 1000 rows in one go :confused:
    Most people don't override the equals method, not needed for beginners.
  8. Offline


    I believe there are people on who are not beginners but doesnt know. Also, thats a draft.

    I think they are good for beginners to prevent them from making habit of coding in the incorrect way, although consequences may not be big, its always better to do the right thing, if its not very hard. Just like replacing Boolean wrapper = true with Boolean wrapper = Boolean.TRUE is not very hard.

    Regarding to the 1000 row thing. I used to create a Statement and call Statement.executeUpdate multiple times for inserting rows of the same table, which is slow. I then changed to PreparedStatement, set the parameters, and do executeUpdate. How that increases the performance?

    I used to use “INSERT INTO test VALUES (1, 3, true)”, then execute it with Statement.executeUpdate. the “1”, “3” and “true” are representing numbers and booleans respectively, instead of strings, but they are passed as string. So, the SQL server needs to parse them, which takes time. If i switch to PrepareStatement, i can initialize it with “INSERT INTO test VALUES (?, ?, ?)”, then do PreparedStatement.setInt(1, 1), setInt(2, 3) and setBoolean(3, true) for setting the parameters, then executeUpdate. During this process, the integers 1 and 3, and the boolean true is passed IN THEIR OWN TYPE to SQL server, instead of String, which SQL server then does not need to parse the parameters. Also, it is proved that the more times you use with a PreparedStatement, the executeUpdate of it will also be faster.

    Then, i switched to use Batch. It allows you to execute multiple statements in a single jdbc call. For Statement, do Statement.addBatch(String sql) and executeBatch. For PreparedStatement, set the parameters and do addBatch for adding another statement that is the same of the string passed for initialization of PreparedStatement. Then, set the parameters again for the second statement. Then do executeBatch.

    EDIT: Collection.singletonList is faster. The implementation of the List behind is only a single object ,while Array.asList constructs an ArrayList
    Last edited: Sep 24, 2018
  9. Offline

    timtower Moderator Moderator

    How often is the Boolean class used then? In comparison to boolean?
    Should be done async anyways, not sure how much you should care about speed by then.
    I agree with the preparedstatements, not just for speed sake (sql injection is an encounter you don't want to have)
    And how much faster is it then? Is it noticeable?
  10. Offline


    Like i said, its always better to do the right thing, even the wrong things do not have serious consequences.

    Sometimes you use Boolean to make the third state or N/A state, which is indicated with null. Sometimes you may use Boolean for generics, since you cannot use boolean for generics.

    Async only prevents affecting the performance of the main thread, doesnt mean its performance is good. You always want to use memory or CPU as less as possible. The optimizations i gave can also reduce network usage or traffics.

    I dont think it is noticeable but why not when its faster and not complex?
  11. Offline

    timtower Moderator Moderator

    @RcExtract Because developers that care about performance will find those things.
    A thread dedicated for performance improvements might be better after all this talk.
    Keep the common mistakes for mistakes, make a new thread for performance things.

    The third state boolean is solved by an enum (why would somebody need a three state thing and be using boolean?)
    Async doesn't mean that performance is good indeed, but something the calls aren't the only thing that can be improved, maybe the rate should be lowered as well (can make big improvements with minimal impact)

    Faster with a sleeping program. If we would want speed then that steady tickrate should be removed.
  12. Offline


    Sorry for getting off topic.

    Dont forget to compare enum with == and UUID with equals
  13. Offline

    timtower Moderator Moderator

    That is a good one to add to be honest, will see when I can do that.
    Want to look into the thread for a rewrite anyways.
Thread Status:
Not open for further replies.

Share This Page