Optimization of java code for reducing complexity [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am actually new to java libraries. I dont know what this code is doing.
I have been given a task to optimize this. Any help will be useful.
I mean to ask whether str.equals(local) checks for entire string aur for particular index value in the for loop.
public void fnc(String str, int[] ar1)
{
String local = "findnumber";
for(int i=0; i<ar1.length; i++)
{
if(str.equals(local) && ar1[i] * 2 > 10)
{
Integer ip = new Integer(ar1[i]);
ip = ip * 2;
System.out.print(ip.toString());
}
}
}

The big O complexity of the algorithm is O(N) where N is the array size. You cannot improve on that ... for the arguments provided and producing the same output.
There are some things that can be done to improve efficiency though.
Hint: look for a computation that is performed on each loop iteration that could be performed once.
Hint: look for some unnecessary object creation1
Hint: unnecessary use of a reference type.
There are one or two other questionable micro-optimizations, but see if you can spot them without any hints. (I say "questionable" because I suspect that the JIT compiler would do the same optimization itself.)
One final note: the actual speed of the code will be dominated by the print statement, and its ability of the OS to write stuff to (for example) the console. And probably by JVM startup / warmup effects ... unless the fnc method is called many times.
1 - Notwithstanding anything else, new Integer(...) is the wrong way to convert an int to an Integer.

Related

Are there any java.util.random seeds with bad/weird properties? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
I'm curious if there are seeds for java.util.random which have weird/surprising properties. This has little practical use, but I'm still curious.
edit: by weird/surprising properties I mean repeating values or atypical patterns.
Yes!
The java.util.Random object's constructor takes in a long as an argument. A bit of sifting through internal classes, we find that this long is processed through the following function:
private static long initialScramble(long seed) {
return (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
}
The goal of this function is to scramble the seed enough so the resulting seed is uniformly distributed across the long range (or something like that).
All we have to do is find an input to this function where it will produce an output of 0 to break things 😊
A bit of brute forcing and I was able to find the long -9223372011639871891
, Using this long as an input, the function returns 0!
Now, we can define a random like the following:
var random = new Random(-9223372011639871891L);
The first call to random.nextInt() will always be zero, no matter the range!
Initial calls to other random functions (nextDouble, nextFloat, etc.) will also produce VERY low values (but not exactly zero)
Of course, this all only applies to the first call to the "next" functions, but still cool regardless!

At what point does writing, maintaining and most importantly the overhead of a function become a viable alternative to repeated code? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've been wondering this for a while, and thought I'd pose the question today.
Example code:
private void createLinks(int numUsers) {
for (int i = 1; i <= numUsers; i++) {
String userId = "ID-" + i;
String randomId;
// Generate an ID to link to.
do {
randomId = "ID-" + random.nextInt(i);
} while (randomId.equals(iUserId));
link(userId, randomId); //links the first argument to the second,
//links are not bi-directional.
// Generate 4 more ID's to link to.
for (int j = 1; j <= 4; j++) {
do {
randomId = "ID-" + random.nextInt(i);
} while (randomId.equals(iUserId));
link(userId, randomId);
link(randomId, userId);
}
// Generate another ID to link
do {
randomId = "ID-" + random.nextInt(i);
} while (randomId.equals(iUserId));
link(randomId, userId)
}
}
#createLinks is invoked a lot, and the do...while code snippet is being repeated in the method. Does it make sense to extract these 3 lines of code out to a method called generateRandomId(int i) and incur the function overhead to avoid this repetition? If createLinks gets invoked a 100 times, generateRandomId would get invoked 100*6 = 600 times.
This is more a language agnostic question rather than one specific to java, but it'd be interesting to know if some languages handle function overhead better than others. E.g. JVM does function inlining to optimize function calls, which might mean that a developer need not wonder about things that I mentioned above.
This is definitely opinion-based question, and I expect it will be closed. But I'll try to answer it anyway, because it's quite frequently asked.
If you want simple answer – don't bother about it. It's probably too soon. Really, the manner you ask a question tells me that you have a lack of information about how frequently this code will be called and how slow it really is. And it's ok. We all face this situation when there are just a lot of unknowns in the context of development. The trick is – those unknown will become knowns in operation context (when your code is actually running). You'll get a feedback about performance issues if any. It should be said, getting this feedback is not so simple task by itself and requires some skills and mature toolchain. But it's not the question you asked.
Does I advocate skip any performance optimization while developing? Of course no, it's silly. There are issues which could and should be solved early. I'm just advising to follow simple and straightforward principle:
If you're in doubt – wait for reality to show you the right way.
This principle could be misused as any other. But I hope you get my point – premature optimization is the root of all evil, right?
My opinionated answer is "always." Whenever I find myself writing the same code twice, I make it a function.
The point where this practice ceases to be opinion-based is when two pieces of code doing exactly the same thing is important to the proper operation of the program.

java boolean array and turning every third value to false [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The Boolean array is initialized to true. I need to know how to turn every third value to false and also going through the array over and over. It is essentially duck duck goose without the randomness.
This sounds like a beginners programming exercise, so I'm going to just give you a hint or two:
Go back to your textbook, lecture notes, tutorial and reread the stuff on for loops. Focus on the old style ones.
Think about how to write a for loop that steps through integer index values in the pattern that you require.
Re "... going through the array over and over" - not sure what you mean, but maybe the hint for this is to think about using nested loops; i.e. a loop inside another loop.
But the most important advice is to try and work this out for yourself.
Well I'm really not sure what you mean by going through the array over and over but the following code will turn every third value to false.
for (int i = 0; i < myVar.length; i++) {
if (i % 3 == 0) {
myVar[i] = false;
}
}
Edit: Oops someone beat me to it while I was typing lol.

when NOT to factor out common code [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Should I trade code-compactness for a bit of performance?
Concretely speaking, which one of the following two is preferable:
// case 0:
final boolean flag = <some condition>;
for (int i = 0; i < SOME_COUNT; ++i)
{
if (flag)
{
// do foo
}
else
{
// do bar
}
}
// case 1:
final boolean flag = <some condition>;
if(flag)
{
for (int i = 0; i < SOME_COUNT; ++i)
{
// do foo
}
}
else
{
for (int i = 0; i < SOME_COUNT; ++i)
{
// do bar
}
}
Prefer the former. For all you know the JIT is able to make the first just as fast as the second.
The rule of thumb with performance: when in doubt, measure. And when you do decide to measure, read this first: How do I write a correct micro-benchmark in Java?
I'd go for the second option, considering the flag attribute is constant and non volatile.
Why would you spend time checking a condition, you already know the result?
Just check it once at the beginning, and do your thing
Please note that you may also find yourself in the need to perform some operations that depend on the flag value, and need to be executed outside the for loop.
In the second case, it's just as easy as adding a new line inside the condition branch
In the first case, you will need to check the condition AGAIN outside the for loop
I'd go with option 0.
Two things:
It's closer to the intention of the code (at least that's how I read your question and, in fact, the code). This will make it easier to maintain the code in the future - it's hard to imagine how much time the change you propose would actually make but I believe the time you save developing will always outscale the savings you'd make by orders of magnitude.
Second, Just-in-time compilation means you might not even doing yourself a favor performancewise because the java virtual machine might find out for you if case 1 is actually better and react accordingly.

Is For loop in reverse better? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Is there any difference in time space complexity for these two?
for (int i=0; i<= 100; i++) {
System.out.println("hi");
}
for (int i=100; i>= 0; i--) {
System.out.println("hi");
}
And what if the loop is larger and complex? Like when i <= 1000000
No, there is no difference in space or time complexity between the two.
I'd be curious to hear why you thought there might be.
P.S. Of course, if the actual code is different, then the answer might be different too.
For these simple loops? No. You're just working with a constant string, some of System.out.println()'s overhead, and an iterated primitive.
However, for more complex nested loops, there could be differences, especially if loops are nested with changing inner loop lengths.
No both has same time space complexity.
As such no difference in time complexity i.e O(N).
Deciding on which approach to follow is your design specific. For example if I have to find largest prime factor of a given number I would probably use 2nd approach. So basically it is design(of your intended project) specific.
For this particular example is not. For larger arrays it might be slower on some systems.
Usually systems are optimized for accessing memory sequentially. As long as memory access pattern is predictable both loops have same efficiency but on older machines or different architectures things may be different.
For space complexity is not (i miss-read the question)
As long as you don't break out of the loop with some logic (depending on index variable) there should be no difference in space/complexity.
If you need to iterate on every single value of your index, going in reverse order is exactly like going in forward.

Categories