• Post Reply Bookmark Topic Watch Topic
  • New Topic

String vs MyStringBuffer.toString()

 
John Peter
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear all,

Now, I am running the load test on 50000 users.

I want to compare the following for application performance tuning purpose:

1. String
Purpose: I will concatanate all the sql string for a db application.
2. StringBuffer with toString method
Purpose:I need to execute SQL statements in JDBC.If I append
all the sql string with StringBuffer, then I need to convert it to String
using toString() method.

A program has been written as follow: (to compare String/StringBuffer)
But I can't differenciate and decide which method is better.



Regards,
John

[added code tags - Jim]
[ April 07, 2005: Message edited by: Jim Yingst ]
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 35719
412
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John,
It is conventional wisdom (don't know if it's still true though) that StringBuffer is faster than String. What did running the program tell you? You probably have to run it more than 1500 times to get noticeable results.

However in your application, the actual JDBC is going to be the bottleneck, not the String concatenation. If you can use a PreparedStatement, do so. This eliminates or at least reduces the need for concatentating the query. For example, "select name from table where id = ?" and stmt.setString(1, "name"). The statement is cached and you don't have to build it from scratch each time.
 
John Peter
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear all,
I have see different results every time running the
benchmark program, it makes me hard to decided which is
better.

The reason I concat string so many time is due to
the SQL is dynamic based on condition in my web application:
e.g:
PreparedStatement ps = null;
ResultSet rs = null;
String strSql=null;
...
strSql="Select col1 from table1 ";

if(fisherman_role!=null)
strSql+="where fisherman_condition...";

if(farmer_role!=null)
strSql+="where farmer_condition...";
....

if(farmer_role!=null && fisherman_role != null)
strSql+="where dual_condition...";
....
Hence, I said the sql will change differently based
on different conditions.

Any contructive idea is welcome.

Regards,
John
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Glad to see you're already using PreparedStatement, because it will also perform the not-so-fun-to-code-yourself database-dependent special character replacement on Strings.

Here are a few things to note.
  • As Jeanne stated, you'll need to use more runs than 1,500 to see noticable results. The more runs you do, the more the numbers should normalize (stop bouncing around between runs).
  • [list]Concatenating String literals is performed by the compiler. is compiled as [/list][list]Concatenating non-literals is rewritten by the compiler to use StringBuffer.where one, two, and three are Strings is compiled asYou pay the toString() penalty either way.[/list]
    Where you save time using StringBuffer directly is when you concatenate in multiple steps. In your SQL-building example, a new StringBuffer and String are created to perform each contatenation. The following will perform better, though as Jeanne pointed at as well, it will perform marginally better, and the savings will pale in comparison to the JDBC execution time.

    Also, if you go the manual StringBuffer route, it can also help to presize it so the buffer won't be reallocated and copied as it gets longer.Also, I bet by now there are some pretty handy JDBC query-building tools out there that provide a nice API that makes dealing with multiple where conditions easier. It gets really tricky when you have two or more optional where conditions.That's two conditions -- imagine how nasty three would look!

    [ I just realized your example does have multiple conditions, so you're probably already aware how tedious this can get. ]
    [ April 07, 2005: Message edited by: David Harkness ]
     
    Ilja Preuss
    author
    Sheriff
    Posts: 14112
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jeanne and David are right: unders specific circumstances, using StringBuffer *will* be faster, but when using them together with JDBC, it quite unlikely will make a noticeable difference.

    The very first thing you should do when you find that your database code isn't performing well is profiling it. Only if you then find out that String concetanation takes a huge amount of time you should start considering using StringBuffer.

    It's quite more likely that you need to performance optimize the database access itself, though (by optimizing the queries or the database, by introduce caching etc.)
     
    steve souza
    Ranch Hand
    Posts: 862
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Glad to see you're already using PreparedStatement, because it will also perform the not-so-fun-to-code-yourself database-dependent special character replacement on Strings.

    What do you mean by this? Can you give an example?
     
    Jeanne Boyarsky
    author & internet detective
    Marshal
    Posts: 35719
    412
    Eclipse IDE Java VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Steve,
    This means that you are protected against SQL injection attacks and the like. For example, suppose I want to do a query that matches a name and the user enters "tara ' and '1' = '1"

    In a regular statement, you have
    "select * from table where name = 'tara ' and '1' = '1'" which will return everything.

    In a prepared statement, you have
    "select * from table where name = 'tara \' and \'1\' = \'1'" which will return nothing.
     
    Aj Mathia
    Ranch Hand
    Posts: 478
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You could consider this approach if the number of possible sql are known and not too large
    class XX
    static private String sql1 = "blah"
    static private String sql2 = "blah"
    static private String sql3 = "blah"
    .
    .
    blah method(){
    if(condition1) ps.prepare(XX.sql1)
    if(condition2) ps.prepare(XX.sql2)
    if(condition3) ps.prepare(XX.sql3)
    rs = ps.executeQuery();

    this will limit the strings from being created for each object reducing your then many temp strings created and soon waiting for gc.

    Secondly
    stringbuffer is better than string with + is NOT true
    both have their place to be used.
    String object is resolved at compile time where as StringBuffer object is resolved at run time. Run time resolution takes place when the value of the string is not known in advance where as compile time resolution happens when the value of the string is known in advance
    so now consider and then decide which is better for your case.
    Finally
    if u have loads of string activites consider using String.intern() for performance
     
    Ilja Preuss
    author
    Sheriff
    Posts: 14112
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Ajay Mathew:

    if u have loads of string activites consider using String.intern() for performance


    This would only improve performance if you do *a lot* of String comparisons, as far as I know. Rather untypical for a DB application, isn't it?
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!