I am doing a benchmark test for my own fun! I have written a part of code in many programming languages and benchmark it using ab to see which is faster and how much. I know the method may not be so valid and can not be used as an evident to use some, but for my own information I am doing so. The other factor I want to know is how easy/difficult is writing the same sample in each language. I wrote the code in Python/Python(asyncio),Haskell,Go, Kotlin and D. I expcted the D port to be faster than Go (or at least equal in speed). But unfortunately my D code is much slower than Go. Here I put oth codes and please help me why the code is not fast as expected. Or am I wrong absolutely in my expectations?
import cbor;
import std.array : appender;
import std.format;
import std.json;
import vibe.vibe;
struct Location
{
float latitude;
float longitude;
float altitude;
float bearing;
}
RedisClient redis;
void main()
{
auto settings = new HTTPServerSettings;
redis = connectRedis("localhost", 6379);
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];
listenHTTP(settings, &hello);
logInfo("Please open http://127.0.0.1:8080/ in your browser.");
runApplication();
}
void hello(HTTPServerRequest req, HTTPServerResponse res)
{
if (req.path == "/locations") {
immutable auto data = req.json;
immutable auto loc = deserializeJson!Location(data);
auto buffer = appender!(ubyte[])();
encodeCborAggregate!(Flag!"WithFieldName".yes)(buffer, loc);
auto db = redis.getDatabase(0);
db.set("Vehicle", cast(string) buffer.data);
res.writeBody("Ok");
}
}
And here is the Go
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
import "github.com/go-redis/redis"
import (
"bytes"
"github.com/2tvenom/cbor"
)
type Location struct {
Latitude float32 `json:"latitude"`
Longitude float32 `json:"longitude"`
Altitude float32 `json:"altitude"`
Bearing float32 `json:"bearing"`
}
func main() {
app := iris.New()
client := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
app.Post("/locations", func(ctx context.Context) {
var loc Location
ctx.ReadJSON(&loc)
var buffTest bytes.Buffer
encoder := cbor.NewEncoder(&buffTest)
encoder.Marshal(loc)
client.Set("vehicle", buffTest.Bytes(), 0)
client.Close()
ctx.Writef("ok")
})
app.Run(iris.Addr(":8080"), iris.WithCharset("UTF-8"))
}
Using ab, Go results in about 4200 req/sec, while D about 2800 req/sec!
You're not just benchmarking Go vs D. You're also benchmarking your particular choice of non-standard Go and D libraries against each other: cbor, vibe, iris, etc. And you're benchmarking your particular implementation which can easily vary by 1000x in performance.
With this many variables, the raw benchmark numbers are pretty meaningless for comparing the performance of two languages. It's possible any one of those 3rd party libraries are causing a performance problem. Really you're comparing just those two particular programs. This is the core problem of trying to compare anything but trivial programs across languages: there's too many variables.
You can reduce the impact of some of these variables with performance profiling; in Go this would be go tool pprof. This will tell you what functions and lines are being called how many times and taking how much resources. With that you can find bottlenecks, places in the code which are consuming a lot of resources, and focus optimization efforts there.
As you do profile and optimization rounds for each version, you'll get closer to comparing real, optimized implementations. Or you'll have a better understanding of what each language and library does efficiently, and what they don't.
The problem of comparing languages is heavily influenced by the particular problem and the particular programmer. X programmers invariably find X to be the best language not because X is the best language, but because X programmers are their best when writing in X and probably chose a problem they're comfortable with. Because of this, there are a number of projects to crowd source the best implementation for each language.
The one which immediately comes to mind is The Computer Language Benchmarks Game. They do Go, but not D. Maybe you can add it?
Related
In the gotour, there is a section: struct literals.
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
What's the difference between a struct with an ampersand and the one without? I know that the ones with ampersands point to the same reference, but why should I use them over the regular ones?
var p = &Vertex{} // why should I use this
var c = Vertex{} // over this
It's true that p (&Vertex{}) has type *Vertex and that c (Vertex{}) has type Vertex.
However, I don't believe that statement really answers the question of why one would choose one over the other. It'd be kind of like answering the question "why use planes over cars" with something like "planes are winged, cars aren't." (Obviously we all know what wings are, but you get the point).
But it also wouldn't be very helpful to simply say "go learn about pointers" (though I think it is a really good idea to so nonetheless).
How you choose basically boils down to the following.
Realize that &Vertex{} and Vertex{} are fundamentally initialized in the same way.
There might be some low-level memory allocation differences (i.e. stack vs heap), but you really should just let the compiler worry about these details
What makes one more useful and performant than the other is determined by how they are used in the program.
"Do I want a pointer to the struct (p), or just the struct (c)?"
Note that you can get a pointer using the & operator (e.g. &c); you can dereference a pointer to get the value using * (e.g. *p)
So depending on what you choose, you may end up doing a lot of *p or &c
Bottom-line: create what you will use; if you don't need a pointer, don't make one (this will help more with "optimizations" in the long run).
Should I use Vertex{} or &Vertex{}?
For the Vertex given in your example, I'd choose Vertex{} to a get a simple value object.
Some reasons:
Vertex in the example is pretty small in terms of size. Copying is cheap.
Garbage collection is simplified, garbage creation may be mitigated by the compiler
Pointers can get tricky and add unnecessary cognitive load to the programmer (i.e. gets harder to maintain)
Pointers aren't something you want if you ever get into concurrency (i.e. it's unsafe)
Vertex doesn't really contain anything worth mutating (just return/create a new Vertex when needed).
Some reasons why you'd want &Struct{}
If Struct has a member caching some state that needs to be changed inside the original object itself.
Struct is huge, and you've done enough profiling to determine that the cost of copying is significant.
As an aside: you should try to keep your structs small, it's just good practice.
You find yourself making copies by accident (this is a bit of a stretch): v := Struct{}
v2 := v // Copy happens
v := &Struct{}
v2 := v // Only a pointer is copied
The comments pretty much spell it out:
v1 = Vertex{1, 2} // has type Vertex
p = &Vertex{1, 2} // has type *Vertex
As in many other languages, & takes the address of the identifier following it. This is useful when you want a pointer rather than a value.
If you need to understand more about pointers in programming, you could start with this for go, or even the wikipedia page.
I have two 16-byte hex values that relate to each other that I want to keep in memory in Go (so they only need to exist for the lifetime of the running process) that can be represented as a simple map like so:
{"aabbcc": "112233"}
Obviously I could represent these as a struct of two strings, but I'm just wondering if there's a faster (i.e. performance) or more memory-efficient way to store the strings in Go? I've only delved into Go lightly so far, so don't know the standard library well enough to know a good answer.
Edit: For an idea of what I'm getting at (in pseudo-code):
I've got two UUIDs from different sources, that are generated/received as strings:
uuid_a_1 = "aabb-1122-3344"
uuid_a_2 = "ddee-5566-7788"
I want to store these in relation to each other:
uuid_map[] = {uuid_a_1: uuid_a_2}
So that I can return one when I lookup the other:
return uuid_map[uuid_a_1]
I'm just curious if there's a more efficient way to store these in memory than a simple map of strings, as I may for example want to store several thousand during the lifetime of the process, and want to be able to key/value store these as quickly as possible (the idea being that because I know the exact size and type of the keys and values that I can do it fast).
As FUZxxl is suggesting you can encode the string to a byte array.
http://play.golang.org/p/7MYWTWSu2-
package main
import (
"encoding/hex"
"fmt"
"strings"
)
func main() {
b, err := hex.DecodeString(strings.Replace("df31a780-f640-11e3-a3ac-0800200c9a66", "-", "", -1))
if err != nil {
fmt.Println(err)
}
fmt.Println("Decoded:", b)
fmt.Println("Encoded:", hex.EncodeToString(b))
}
The following is incompatible with the Dart Style Guide. Should I not do this? I'm extending the num class to build a unit of measure library for medical applications. Using lower case looks more elegant than Kg or Lbs. In some cases using lower case is recommended for safety i.e. mL instead of Ml.
class kg extends num {
String uom = "kg";
num _value;
lbs toLbs() => new lbs(2.20462 * _value);
}
class lbs extends num {
String uom = "lbs";
num _value;
kg toKg() => new kg(_value/2.20462);
}
For your case I might pick a unit (e.g. milligrams) and make other units multiples of it. You can use division for conversion:
const mg = 1; // The unit
const g = mg * 1000;
const kg = g * 1000;
const lb = mg * 453592;
main() {
const numPoundsPerKilogram = kg / lb;
print(numPoundsPerKilogram); // 2.20462...
const twoPounds = lb * 2;
const numGramsInTwoPounds = twoPounds / g;
print(numGramsInTwoPounds); // 907.184
}
It's best to make the unit small, so other units can be integer multiples of it (ints are arbitrary precision).
It's up to you if you use them.
There might be situations where it can be important.
One I can think of currently is when you have an open source project and you don't want to alienate potential contributors.
When you have no special reason stick with the guidelines, if you have a good reason deviate from it.
Don't use classes for units. Use them for quantities:
class Weight {
static const double LBS_PER_KG = 2.20462;
num _kg;
Weight.fromKg(this._kg);
Weight.fromLbs(lbs) {
this._kg = lbs / LBS_PER_KG;
}
get inKg => _kg;
get inLbs => LBS_PER_KG * _kg;
}
take a look at the Duration class for ideas.
Coding conventions serve to help you write quality, readable code. If you find that ignoring a certain convention helps to improve the readability, that is your decision.
However, code is rarely only seen by one pair of eyes. Other programmers will be confused when reading your code if it doesn't follow the style guide. Following coding conventions allows others to quickly dive into your code and easily understand what is going on. Of course, it is possible that you really will be the only one to ever view this code, in which case this is moot.
I would avoid deviating from the style guide in most cases, except where the advantage is very obvious. For your situation I don't the advantage outweighs the disadvantage.
I wouldn't really take those coding standards too seriously.
I think these guidelines are much more reasonable: less arbitrary, and more useful:
Java: Code Conventions
Javascript: http://javascript.crockford.com/code.html
There are many more you can choose from - pick whatever works best for you!
PS:
As long as you're talking about Dart, check out this article:
Google Dart to ultimately replace Javascript ... not!
as i mentioned on subject of this post i found out OOP is slower than Structural Programming(spaghetti code) in the hard way.
i writed a simulated annealing program with OOP then remove one class and write it structural in main form. suddenly it got much faster . i was calling my removed class in every iteration in OOP program.
also checked it with Tabu Search. Same result .
can anyone tell me why this is happening and how can i fix it on other OOP programs?
are there any tricks ? for example cache my classes or something like that?
(Programs has been written in C#)
If you have a high-frequency loop, and inside that loop you create new objects and don't call other functions very much, then, yes, you will see that if you can avoid those news, say by re-using one copy of the object, you can save a large fraction of total time.
Between new, constructors, destructors, and garbage collection, a very little code can waste a whole lot of time.
Use them sparingly.
Memory access is often overlooked. The way o.o. tends to lay out data in memory is not conducive to efficient memory access in practice in loops. Consider the following pseudocode:
adult_clients = 0
for client in list_of_all_clients:
if client.age >= AGE_OF_MAJORITY:
adult_clients++
It so happens that the way this is accessed from memory is quite inefficient on modern architectures because they like accessing large contiguous rows of memory, but we only care for client.age, and of all clients we have; those will not be laid out in contiguous memory.
Focusing on objects that have fields results into data being laid out in memory in such a way that fields that hold the same type of information will not be laid out in consecutive memory. Performance-heavy code tends to involve loops that often look at data with the same conceptual meaning. It is conducive to performance that such data be laid out in contiguous memory.
Consider these two examples in Rust:
// struct that contains an id, and an optiona value of whether the id is divisible by three
struct Foo {
id : u32,
divbythree : Option<bool>,
}
fn main () {
// create a pretty big vector of these structs with increasing ids, and divbythree initialized as None
let mut vec_of_foos : Vec<Foo> = (0..100000000).map(|i| Foo{ id : i, divbythree : None }).collect();
// loop over all hese vectors, determine if the id is divisible by three
// and set divbythree accordingly
let mut divbythrees = 0;
for foo in vec_of_foos.iter_mut() {
if foo.id % 3 == 0 {
foo.divbythree = Some(true);
divbythrees += 1;
} else {
foo.divbythree = Some(false);
}
}
// print the number of times it was divisible by three
println!("{}", divbythrees);
}
On my system, the real time with rustc -O is 0m0.436s; now let us consider this example:
fn main () {
// this time we create two vectors rather than a vector of structs
let vec_of_ids : Vec<u32> = (0..100000000).collect();
let mut vec_of_divbythrees : Vec<Option<bool>> = vec![None; vec_of_ids.len()];
// but we basically do the same thing
let mut divbythrees = 0;
for i in 0..vec_of_ids.len(){
if vec_of_ids[i] % 3 == 0 {
vec_of_divbythrees[i] = Some(true);
divbythrees += 1;
} else {
vec_of_divbythrees[i] = Some(false);
}
}
println!("{}", divbythrees);
}
This runs in 0m0.254s on the same optimization level, — close to half the time needed.
Despite having to allocate two vectors instead of of one, storing similar values in contiguous memory has almost halved the execution time. Though obviously the o.o. approach provides for much nicer and more maintainable code.
P.s.: it occurs to me that I should probably explain why this matters so much given that the code itself in both cases still indexes memory one field at a time, rather than, say, putting a large swath on the stack. The reason is c.p.u. caches: when the program asks for the memory at a certain address, it actually obtains, and caches, a significant chunk of memory around that address, and if memory next to it be asked quickly again, then it can serve it from the cache, rather than from actual physical working memory. Of course, compilers will also vectorize the bottom code more efficiently as a consequence.
Using Go I'm trying to find the "best" way to format a floating point number into a string. I've looked for examples however I cannot find anything that specifically answers the questions I have. All I want to do is use the "best" method to format a floating point number into a string. The number of decimal places may vary but will be known (eg. 2 or 4 or zero).
An example of what I want to achieve is below.
Based on the example below should I use fmt.Sprintf() or strconv.FormatFloat() or something else?
And, what is the normal usage of each and differences between each?
I also don't understand the significance of using either 32 or 64 in the following which currently has 32:
strconv.FormatFloat(float64(fResult), 'f', 2, 32)
Example:
package main
import (
"fmt"
"strconv"
)
func main() {
var (
fAmt1 float32 = 999.99
fAmt2 float32 = 222.22
)
var fResult float32 = float32(int32(fAmt1*100) + int32(fAmt2*100)) / 100
var sResult1 string = fmt.Sprintf("%.2f", fResult)
println("Sprintf value = " + sResult1)
var sResult2 string = strconv.FormatFloat(float64(fResult), 'f', 2, 32)
println("FormatFloat value = " + sResult2)
}
Both fmt.Sprintf and strconv.FormatFloat use the same string formatting routine under the covers, so should give the same results.
If the precision that the number should be formatted to is variable, then it is probably easier to use FormatFloat, since it avoids the need to construct a format string as you would with Sprintf. If it never changes, then you could use either.
The last argument to FormatFloat controls how values are rounded. From the documentation:
It rounds the
result assuming that the original was obtained from a floating-point
value of bitSize bits (32 for float32, 64 for float64)
So if you are working with float32 values as in your sample code, then passing 32 is correct.
You will have with Go 1.12 (February 2019) and the project cespare/ryu a faster alternative to strconv:
Ryu is a Go implementation of Ryu, a fast algorithm for converting floating-point numbers to strings.
It is a fairly direct Go translation of Ulf Adams's C library.
The strconv.FormatFloat latency is bimodal because of an infrequently-taken slow path that is orders of magnitude more expensive (issue 15672).
The Ryu algorithm requires several lookup tables.
Ulf Adams's C library implements a size optimization (RYU_OPTIMIZE_SIZE) which greatly reduces the size of the float64 tables in exchange for a little more CPU cost.
For a small fraction of inputs, Ryu gives a different value than strconv does for the last digit.
This is due to a bug in strconv: issue 29491.
Go 1.12 might or might not include that new implementation directly in strconv, but if it does not, you can use this project for faster conversion.