I want to do a potentially costly calculation once, to use its result to initialise two class properties that ideally should be vals. Is there a correct way of doing this?
eg:
class Foo(aIn: Double, bIn: Double) {
val a = aIn * bigCalc(aIn, bIn)
val b = bIn * bigCalc(aIn, bIn)
}
I cannot do it in an init block because the result cannot be accessed outside that, I would prefer not to make a and b vars as they should be immutable, and I would rather not leave it as in the example as this would be slow for no good reason.
You can actually use init
class Foo(aIn: Double, bIn: Double) {
val a: Double
val b: Double
init {
a = aIn * bigCalc(aIn, bIn)
b = bIn * bigCalc(aIn, bIn)
}
}
However this is same as the code you have. Both initialize the variables when the class is created. So using init doesn't improve performance. Check this similar SO answer.
Related
While refactoring my F# code, I found a record with a field of type bool ref:
type MyType =
{
Enabled : bool ref
// other, irrelevant fields here
}
I decided to try changing it to a mutable field instead
// Refactored version
type MyType =
{
mutable Enabled : bool
// other fields unchanged
}
Also, I applied all the changes required to make the code compile (i.e. changing := to <-, removing incr and decr functions, etc).
I noticed that after the changes some of the unit tests started to fail.
As the code is pretty large, I can't really see what exactly changed.
Is there a significant difference in implementation of the two that could change the behavior of my program?
Yes, there is a difference. Refs are first-class values, while mutable variables are a language construct.
Or, from a different perspective, you might say that ref cells are passed by reference, while mutable variables are passed by value.
Consider this:
type T = { mutable x : int }
type U = { y : int ref }
let t = { x = 5 }
let u = { y = ref 5 }
let mutable xx = t.x
xx <- 10
printfn "%d" t.x // Prints 5
let mutable yy = u.y
yy := 10
printfn "%d" !u.y // Prints 10
This happens because xx is a completely new mutable variable, unrelated to t.x, so that mutating xx has no effect on x.
But yy is a reference to the exact same ref cell as u.y, so that pushing a new value into that cell while referring to it via yy has the same effect as if referring to it via u.y.
If you "copy" a ref, the copy ends up pointing to the same ref, but if you copy a mutable variable, only its value gets copied.
You have the difference not because one is first-value, passed by reference/value or other things. It's because a ref is just a container (class) on its own.
The difference is more obvious when you implement a ref by yourself. You could do it like this:
type Reference<'a> = {
mutable Value: 'a
}
Now look at both definitions.
type MyTypeA = {
mutable Enabled: bool
}
type MyTypeB = {
Enabled: Reference<bool>
}
MyTypeA has a Enabled field that can be directly changed or with other word is mutable.
On the other-side you have MyTypeB that is theoretically immutable but has a Enabled that reference to a mutable class.
The Enabled from MyTypeB just reference to an object that is mutable like the millions of other classes in .NET. From the above type definitions, you can create objects like these.
let t = { MyTypeA.Enabled = true }
let u = { MyTypeB.Enabled = { Value = true }}
Creating the types makes it more obvious, that the first is a mutable field, and the second contains an object with a mutable field.
You find the implementation of ref in FSharp.Core/prim-types.fs it looks like this:
[<DebuggerDisplay("{contents}")>]
[<StructuralEquality; StructuralComparison>]
[<CompiledName("FSharpRef`1")>]
type Ref<'T> =
{
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
mutable contents: 'T }
member x.Value
with get() = x.contents
and set v = x.contents <- v
and 'T ref = Ref<'T>
The ref keyword in F# is just the built-in way to create such a pre-defined mutable Reference object, instead that you create your own type for this. And it has some benefits that it works well whenever you need to pass byref, in or out values in .NET. So you should use ref. But you also can use a mutable for this. For example, both code examples do the same.
With a reference
let parsed =
let result = ref 0
match System.Int32.TryParse("1234", result) with
| true -> result.Value
| false -> result.Value
With a mutable
let parsed =
let mutable result = 0
match System.Int32.TryParse("1234", &result) with
| true -> result
| false -> result
In both examples you get a 1234 as an int parsed. But the first example will create a FSharpRef and pass it to Int32.TryParse while the second example creates a field or variable and passes it with out to Int32.TryParse
please consider the below code,
class A {
foo() {
int a = logicToGetA();
int _bar() => someOtherLogic(a);
// ..
int b = _bar();
// ..
}
}
class B {
int _bar(int a) => someOtherLogic(a);
foo() {
int a = logicToGetA();
// ..
int b = _bar(a);
// ..
}
}
main() {
for (int i = 0; i < 1000000; i++) {
A().foo();
}
for (int i = 0; i < 1000000; i++) {
B().foo();
}
}
Explanation: class A has bar() nested inside foo() but class B has bar() outside of foo(). in the second case, bar() can be made as a static method as well.
My Doubt: which way is more efficient, if foo() is called multiple times? If A().foo() is called 1000000 times, will A.foo.bar is redefined that many times?
It depends.
If the _bar function can be defined outside of the foo method, then we can presume that it doesn't reference any local variables of the foo method.
In that case, the compiler can optimize the local function to be just as efficient as the instance method. Maybe it does, maybe it doesn't, so let's check.
See: https://dartpad.dev/4a53a91bf4e0006e4af4c8a598b68ee6 .
This is (attempted) written so that the compiler can't optimize away the invocation of _someOtherLogic.
I also tried making the invocation be to a static method (but then having to pass the object itself as argument to give access to the instance getter for flag).
Running this in dartpad gives me a final set of results of
A: 918460 /ms
B: 798960 /ms
S: 918380 /ms
It seems dart2js is more efficient with the local function than with the instance method.
Running the same code on the VM gives a benchmark result of:
A: 625960.0 /ms
B: 723245.0 /ms
S: 625075.0 /ms
showing that it's performance characteristics are exactly the opposite of dart2js.
It's very likely that dart2js inlines the _bar function when it's statically known. The dart2js compiler tend to be more aggressive about inlining than the VM.
All in all, I wouldn't start to worry about this difference unless the function call shows up heavily in the performance profile of a real-world program.
If your program's performance really depends critically on this one function call, I'd probably inline the function. If not, write whatever is more readable and maintainable, and don't start micro-optimizing until you know it matters.
I would like to know the best/correct way to get back to the initial values of an object without playing with delete and new (everything must stay on the stack)
With this 2 classes:
static const int defaultValue{15};
class Foo
{
private:
int val1{defaultValue};
short val2{4};
}
class LongStandingObject
{
public:
void resetFoo(int index);
private:
Foo foos[100];
}
If I need to reset some foos to their default values, what is the best way?
Create reset method in Foo
void Foo::reset()
{
val1 = defaultValue;
val2 = 4;
}
I don't really like the idea to have the values coming from 2 differents places and I do like to have the defaults values in the header next to the variable declaration.
Replace by a locally created Foo
void LongStandingObject::resetFoo(int index)
{
foos[index] = Foo();
}
Am I heading to trouble when the local variable is destroyed?
Use memcpy
void LongStandingObject::resetFoo(int index)
{
Foo foo;
memcpy(foos[index], &foo, sizeof(Foo));
}
Maybe less readable...
Any other method?
Your #2 is just fine, and probably the most legible.
void LongStandingObject::resetFoo(int index)
{
foos[index] = Foo();
}
There are no object lifetime issues here: the assignment operator is called on foos[index] to change its values to match the temporary object materialized from Foo(). That is, the code is exactly equivalent to
{
Foo tmp;
foos[index].val1 = tmp.val1;
foos[index].val2 = tmp.val2;
}
And if optimizations are enabled, almost any compiler will be able to just modify foos[index] directly without actually creating the temporary Foo.
If you do want a Foo::reset() function as well, you can use the same idea for it:
void Foo::reset()
{
*this = Foo();
}
I would avoid using memcpy, since the program would become incorrect if you ever make changes to Foo that make it no longer trivially copyable.
What you can do is to use std::pair on each variable. Initialized with with variable.first = variable.second = value. After, every time you want to update the variable you set: variable.second = new_value. When you want to restore to the original, you set: variable.second = variable.first. You can improve it by writing a macro RestoreDefault(var) to make the code more readable.
For example:
#define RestoreDefault(var) ((var).second = (var).first)
// int val1{180}; // Instead of this line
std::pair<int,int> val1{ 180,180}; // <- this line
val1.second = 456;
RestoreDefault(val1);
If you want to hardcoded block any possibility to re-set later the default value, write:
std::pair<const int,int> val1{ 180,180}; // <- this line
-
Addition: Same principle for array:
class Foo
{
public:
int x = 100;
int y = 200;
};
#define RestoreArrDefault(var) ((var).second.fill((var).first))
// Use:
std::pair<Foo, std::array<Foo, 100>> FooAr, FooAr2;
// You can define different arrays with different defaults:
FooAr.first = { 180,360 }; // <- Customize FooAr defaults
// In that point FooAr default is 180,360 and FooAr2 default is 100,200
FooAr.second[3] = { 2,10 }; // <- Edit FooAr index-3 item
RestoreArrDefault(FooAr); // <- Restore Default
Basically, I am looking for something more or less equivalent to the following C code:
int theGlobalCount = 0;
int
theGlobalCount_get() { return theGlobalCount; }
void
theGlobalCount_set(int n) { theGlobalCount = n; return; }
You could use a neat trick: declare a mutable global variable, and make a ref (aka mutable reference) point to it (no GC is required to make this work!). Then, implement functions to provide access to the mutable reference.
local
var theGlobalCount_var : int = 0
val theGlobalCount = ref_make_viewptr (view# theGlobalCount_var | addr# theGlobalCount_var)
in // in of [local]
fun
theGlobalCount_get () : int = ref_get_elt (theGlobalCount)
fun
theGlobalCount_set (n: int): void = ref_set_elt (theGlobalCount, n)
end // end of [local]
Note that declarations inside local-in are visible only to code inside in-end. Therefore, neither theGlobalCount_var nor theGlobalCount are visible outside the scope of the local.
Full code: glot.io
You can also use the extvar feature to update an external global variable (declared in the target language). This is very useful if you compile ATS to a language that does not support explicit pointers (e.g., JavaScript). Here is a running example that makes use of this feature:
http://www.ats-lang.org/SERVER/MYCODE/Patsoptaas_serve.php?mycode_url=http://pastebin.com/raw/MsXhVE0A
Say I have a list of names.
case class Name(val first: String, val last: String)
val names = Name("c", "B") :: Name("b", "a") :: Name("a", "B") :: Nil
If I now want to sort that list by last name (and if that is not enough, by first name), it is easily done.
names.sortBy(n => (n.last, n.first))
// List[Name] = List(Name(a,B), Name(c,B), Name(b,a))
But what, if I‘d like to sort this list based on some other collation for strings?
Unfortunately, the following does not work:
val o = new Ordering[String]{ def compare(x: String, y: String) = collator.compare(x, y) }
names.sortBy(n => (n.last, n.first))(o)
// error: type mismatch;
// found : java.lang.Object with Ordering[String]
// required: Ordering[(String, String)]
// names.sortBy(n => (n.last, n.first))(o)
is there any way that allow me to change the ordering without having to write an explicit sortWith method with multiple if–else branches in order to deal with all cases?
Well, this almost does the trick:
names.sorted(o.on((n: Name) => n.last + n.first))
On the other hand, you can do this as well:
implicit val o = new Ordering[String]{ def compare(x: String, y: String) = collator.compare(x, y) }
names.sortBy(n => (n.last, n.first))
This locally defined implicit will take precedence over the one defined on the Ordering object.
One solution is to extend the otherwise implicitly used Tuple2 ordering. Unfortunately, this means writing out Tuple2 in the code.
names.sortBy(n => (n.second, n.first))(Ordering.Tuple2(o, o))
I'm not 100% sure what methods you think collator should have.
But you have the most flexibility if you define the ordering on the case class:
val o = new Ordering[Name]{
def compare(a: Name, b: Name) =
3*math.signum(collator.compare(a.last,b.last)) +
math.signum(collator.compare(a.first,b.first))
}
names.sorted(o)
but you can also provide an implicit conversion from a string ordering to a name ordering:
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
3*math.signum(os.compare(a.last,b.last)) + math.signum(os.compare(a.first,b.first))
}
and then you can use any String ordering to sort Names:
def oo = new Ordering[String] {
def compare(x: String, y: String) = x.length compare y.length
}
val morenames = List("rat","fish","octopus")
scala> morenames.sorted(oo)
res1: List[java.lang.String] = List(rat, fish, octopus)
Edit: A handy trick, in case it wasn't apparent, is that if you want to order by N things and you're already using compare, you can just multiply each thing by 3^k (with the first-to-order being multiplied by the largest power of 3) and add.
If your comparisons are very time-consuming, you can easily add a cascading compare:
class CascadeCompare(i: Int) {
def tiebreak(j: => Int) = if (i!=0) i else j
}
implicit def break_ties(i: Int) = new CascadeCompare(i)
and then
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
os.compare(a.last,b.last) tiebreak os.compare(a.first,b.first)
}
(just be careful to nest them x tiebreak ( y tiebreak ( z tiebreak w ) ) ) so you don't do the implicit conversion a bunch of times in a row).
(If you really need fast compares, then you should write it all out by hand, or pack the orderings in an array and use a while loop. I'll assume you're not that desperate for performance.)