// code in atoi.go, line 90
var cutoff uint64
switch base {
case 10:
cutoff = maxUint64/10 + 1
case 16:
cutoff = maxUint64/16 + 1
default:
cutoff = maxUint64/uint64(base) + 1
}
I saw some code in file atoi.go of Golang package, why not write it like below?
var cutoff = maxUint64/uint64(base) + 1
Thanks a lot.
I think the comment above the line you are referring to may answer your question:
// Use compile-time constants for common cases.
Because maxUint64/10 + 1 and maxUint64/16 + 1 only reference constants the compiler can calculate this. The result is that there is no need to perform the division operation at runtime every time ParseUint is called. You can see the benchmarks in the commit.
Related
I have a function like this:
fun randomWalk(numSteps: Int): Int {
var n = 0
repeat(numSteps) { n += (-1 + 2 * Random.nextInt(2)) }
return n.absoluteValue
}
This works fine, except that it uses a mutable variable, and I would like to make everything immutable when possible, for better safety and readability. So I came up with an equivalent version that doesn't use any mutable variables:
fun randomWalk_seq(numSteps: Int): Int =
generateSequence(0) { it + (-1 + 2 * Random.nextInt(2)) }
.elementAt(numSteps)
.absoluteValue
This also works fine and produces the same results, but it takes 3 times longer.
I used the following way to measure it:
#OptIn(ExperimentalTime::class)
fun main() {
val numSamples = 100000
val numSteps = 15708
repeat(5) {
val randomWalkSamples: IntArray
val duration = measureTime {
randomWalkSamples = IntArray(numSamples) { randomWalk(numSteps) }
}
println(duration)
}
}
I know it's a bit hacky (I could have used JMH but this is just a quick test - at least I know that measureTime uses a monotonic clock). The results for the iterative (mutable) version:
2.965358406s
2.560777033s
2.554363661s
2.564279403s
2.608323586s
As expected, the first line shows it took a bit longer on the first run due to the warming up of the JIT, but the next 4 lines have fairly small variation.
After replacing randomWalk with randomWalk_seq:
6.636866719s
6.980840906s
6.993998111s
6.994038706s
7.018054467s
Somewhat surprisingly, I don't see any warmup time - the first line is always lesser duration than the following 4 lines, every time I run this. And also, every time I run it, the duration keeps increasing, with line 5 always being the greatest duration.
Can someone explain the findings, and also is there any way of making this function not use any mutable variables but still have performance that is close to the mutable version?
Your solution is slower for two main reasons: boxing and the complexity of the iterator used by generateSequence()'s Sequence implementation.
Boxing happens because a Sequence uses its types generically, so it cannot use primitive 32-bit Ints directly, but must wrap them in classes and unwrap them when retrieving the items.
You can see the complexity of the iterator by Ctrl+clicking the generateSequence function to view the source code.
#Михаил Нафталь's suggestion is faster because it avoids the complex iterator of the sequence, but it still has boxing.
I tried writing an overload of sumOf that uses IntProgression directly instead of Iterable<T>, so it won't use boxing, and that resulted in equivalent performance to your imperative code with the var. As you can see, it's inline and when put together with the { -1 + 2 * Random.nextInt(2) } lambda suggested by #Михаил Нафталь, then the resulting compiled code will be equivalent to your imperative code.
inline fun IntProgression.sumOf(selector: (Int) -> Int): Int {
var sum: Int = 0.toInt()
for (element in this) {
sum += selector(element)
}
return sum
}
Ultimately, I don't think you're buying yourself much in the way of code clarity by removing a single var in such a small function. I would say the sequence code is arguably harder to read. vars may add to code complexity in complex algorithms, but I don't think they do in such simple algorithms, especially when there's only one of them and it's local to the function.
Equivalent immutable one-liner is:
fun randomWalk2(numSteps: Int) =
(1..numSteps).sumOf { -1 + 2 * Random.nextInt(2) }.absoluteValue
Probably, even more performant would be to replace
with
so that you'll have one multiplication and n additions instead of n multiplications and (2*n-1) additions:
fun randomWalk3(numSteps: Int) =
(-numSteps + 2 * (1..numSteps).sumOf { Random.nextInt(2) }).absoluteValue
Update
As #Tenfour04 noted, there is no specific stdlib implementation for IntProgression.sumOf, so it's resolved to Iterable<T>.sumOf, which will add unnecessary overhead for int boxing.
So, it's better to use IntArray here instead of IntProgression:
fun randomWalk4(numSteps: Int) =
(-numSteps + 2 * IntArray(numSteps).sumOf { Random.nextInt(2) }).absoluteValue
Still encourage you to check this all with JMH
I think:"Removing mutability without losing speed" is wrong title .because
mutability thing comes to deal with the flow that program want to achieve .
you are using var inside function.... and 100% this var will not ever change from outside this function and that is mutability concept.
if we git rid off from var everywhere why we need it in programming ?
I am following an instructor creating tic tac toy game, to make it autoplay.
var r = Random()
val randInt = r.nextInt(emptyCell.size-0) + 0 // adding 0 here
why do we need to add +0 here?
There's no reason why you'd have to write down + 0 in that case. nextInt returns an Int, so adding 0 as an Int to it does absolutely nothing - doesn't change the type or affect the value - as you'd expect.
Probably a typo in the tutorial.
It's a billet for changing a value if you wish to. Author just showed you where and how to put it to.
Here's how your code should look like:
var random = Random()
var randomIndex: Int?
randomIndex = random.nextInt(emptyCell.size - 1) + 2 // two values instead of 00
println("randomIndex $randomIndex")
val emptyCellId = emptyCell[randomIndex]
println("emptyCellId $emptyCellId")
var btnSelect: Button?
btnSelect = setButtonId(noOfCards, emptyCellId)
Adding 0 will work but it does not change anything.
Note that you are using Java's java.util.Random which would limit your code to the JVM.
If you use kotlin.random.Random your code will target all platforms that Kotlin does and would be simpler because you don't need to instantiate a class.
You can use it like this:
val randInt = Random.nextInt(emptyCell.size)
Check out the other variants of nextInt if you don't need to specify bonds or you need to specify an upper bound.
I am currently writing a Swift application and parts of it require making sure certain user inputs add up to a specified value.
A simplified example:
Through program interaction, the user has specified that totalValue = 67 and that turns = 2. This means that in two inputs, the user will have to provide two values that add up to 67.
So lets say on turn 1 the user enters 32, and then on turn 2 he enters 35, this would be valid because 32 + 35 = 67.
This all works fine, but the moment we verge into more than one decimal place, the program cannot add the numbers correctly. For example, if totalValue = 67 and then on turn 1 the user enters 66.95 and then on turn 2 he enters .05 the program will return that this is an error despite the fact that
66.95 + .05 = 67. This problem does not happen with one decimal place or less (something like turn 1 = 55.5 and turn 2 = 11.5 works fine), only for two decimal spots and beyond. I am storing the values as doubles. Thanks in advance
Some example code:
var totalWeights = 67
var input = Double(myTextField.text.bridgeToObjectiveC().doubleValue)
/*Each turn is for a button click*/
/*For turn 1*/
if inputValid == true && turn == 1 && input < totalWeights
{
myArray[0] = input
}
else
{
//show error string
}
/*For turn 2*/
if inputValid == true && turn == 2 && input == (totalWeights - myArray[0])
{
myArray[1] = input
}
else
{
//show error string
}
If you want exact values from floating point then the float/double types will not work, as they are only ever approximations of exact numbers. Look into using the NSDecimalNumber class from within Swift, I'm not sure what the bridging would look like but it should be simple.
Here is an example of how this could work:
var a = 0
for num in numlist {
a += num
}
var result = false
if a == targetnum
result = true
I haven't tested this out, but if numlist is an array of double then it should work for any input that is a valid number.
One problem I just realized is that there is an issue with doing an equals with doubles, as rounding will cause problems for you. I am not going to show it, but if, while reading in the inputs you keep track of how many numbers to the right of the decimal place, then multiply all of the values by that number of tens, so 66.95 * 100 to get it all as an integer, then add, then do the comparison, after multiplying the targetnum by the same value (100).
Unfortunately there is no ideal solution to this. We must use approximation type comparison.
For example, instead of checking:
if val1 == val2
we must try something like:
if val1 > (val2 - .0005) && val1 < (val2 + .0005)
I wanted to calculate the power sum S_p(x) = 1^p + 2^p + 3^p + ... + x^p using the code
powersum[x_,p_]:=sum=0;For[i=1,i<x,i++,sum=sum+i^p];sum
but it seems to output 0 every time. Why does it do that?
As written, Mathematica is parsing your expression like this:
powersum[x_,p_]:=sum=0; (*Definition ended here*)
For[i=1,i<x,i++,sum=sum+i^p];
sum
You need to use to wrap your expression in parenthesis to make them all part of the function definition.
powersum[x_,p_]:=(sum=0;For[i=1,i<x,i++,sum=sum+i^p];sum)
Often it is preferable to use Module[]:
powersum[x_,p_]:=Module[{sum},sum=0;For[i=1,i<x,i++,sum=sum+i^p];sum]
or
powersum[x_,p_]:=Module[{sum=0},For[i=1,i<x,i++,sum=sum+i^p];sum]
this is essentially the same as wrapping in () except sum is protected in a local context.
of course for this example you could as well use :
powersum[x_,p_]:=Sum[i^p,{i,1,x-1}]
or
powersum[x_, p_] := Range[x - 1]^p // Total
I need to write a recursive function that utilizes just two string methods, .empty? and .chop.
No, I can't use .length (Can you tell it's homework yet?)
So far I'm stuck on writing the function itself, I passed it the string, but I am unsure on how to recursively go through the characters with the .chop string method. Would I just have a counter? Syntax for this thing seems tricky to me.
def stringLength(string)
if string.empty?
return 0
else
.....
end
end
I wish I could put more down, but this is what I'm stuck at.
return 1 + stringLength(string.chop)
Thats your missing line. Here is an example of how this will work:
stringLength("Hello") = 1 + stringLength("Hell")
stringLength("Hell") = 1 + stringLength("Hel")
stringLength("Hel") = 1 + stringLength("He")
stringLength("He") = 1 + stringLength("H")
stringLength("H") = 1 + stringLength("")
stringLength("") = 0