Appaling RazorEngine 3.3 performance, compared to StringTemplate4 - razor

Is there any reason or anything I am doing wrong, why RazorEngine is so slow just to parse 100 different templates? I was looking into StringTemplate, and performed two tests to compare, as per below.
[Test]
public void TestStringTemplate()
{
CsStopwatch stopwatch = new CsStopwatch();
stopwatch.Start();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
string template = #"Hello there my name is <Name> <Surname> " + i;
TextParseTests.TestModel model = new TextParseTests.TestModel();
model.Name = "Karl";
model.Surname = "Cassar";
Template t = new Template(template);
t.Add("Name", model.Name);
t.Add("Surname", model.Surname);
var result = t.Render();
sb.AppendLine(result);
}
stopwatch.Stop();
var ms = stopwatch.ElapsedMilliseconds;
int k = 5;
//109ms
}
[Test]
public void TestRazorEngine()
{
CsStopwatch stopwatch = new CsStopwatch();
stopwatch.Start();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
string template = #"Hello there my name is #Model.Name #Model.Surname " + i;
TextParseTests.TestModel model = new TextParseTests.TestModel();
model.Name = "Karl";
model.Surname = "Cassar";
var result = Razor.Parse(template, model);
sb.AppendLine(result);
}
stopwatch.Stop();
var ms = stopwatch.ElapsedMilliseconds;
int k = 5;
//24000~ ms
}
The difference is staggering.
StringTemplatev4: 109ms
RazorEngine 3.3: 24,131ms
That is over 200x slower than StringTemplate! I have a lot of content using the RazorEngine format, and I prefer the syntax for RazorEngine way over StringTemplate. However, this is extremely, extremely slow.
Any ideas if I may be doing anything wrong? Please note that I am using different templates on purpose, as if I use caching for RazorEngine it is way faster (down to 300 - 400ms) but my website has a lot of tiny text which are different, and this is the most 'real-life' test I could do.

Razor.Parse will compile the template every time.
You shouldn't do this. Your application should compile the template once, or whenever the template is changed if the template is being modified whilst the application is running.
Razor.Compile(template, name);
Following this your application should use
Razor.Run(name, model);
Compare the times against Razor.Run not Razor.Parse

Related

Performance in multithreaded Json.NET serialization

We're deserializing large JSON payloads from an external API, each response being roughly 30MB.
On my developer machine it takes 0.3s to call JsonConvert.DeserializObject(jsonString) with those 30MB in a single thread. But if I deserialize in multiple threads the time spent per deserialization drastically increases as the number of threads increases, up to 5-10s sometimes. My test code looks like this:
var json = System.IO.File.ReadAllText("c:/largejson.json");
var count = 100;
var ops = 0;
var results = new ConcurrentBag<TimeSpan>();
while (ops < count)
{
var tasks = new List<Task>();
for (var i = 0; i < Environment.ProcessorCount; i++)
{
tasks.Add(Task.Run(() =>
{
var stopwatch = new Stopwatch();
stopwatch.Start();
JsonConvert.DeserializeObject(json);
ops++;
stopwatch.Stop();
results.Add(stopwatch.Elapsed);
}
));
}
await Task.WhenAll(tasks);
}
var totalSeconds = results.Sum(r => r.TotalSeconds);
var secondsPerOp = totalSeconds / ops;
And here's the file I'm using: https://github.com/andersekdahl/files/blob/master/largejson.json
I've tested both with and without passing in a new JsonSerializerSettings() as a second argument but it doesn't make any difference.
My first instinct was that there was some locking inside Json.NET but when I profiled it using dotTrace nothing really sticks out. A lot of time is spent in JTokenWriter.WritePropertyName but that doesn't look like it's shared between threads/deserializations.
Anyone has any clues what's causing the slowdown?

How to make housie / bingo game in Flash AS3

It shows an error when written this script has a package that cannot be nested how can I resolve the problem.
If not can anyone give me a new code so that I can try to make the new file?
I have this file in previous stack AS3 Bingo ticket generator
but i couldnt understan how to use it.
package {
import flash.display.Sprite;
import flash.text.TextField;
public class Main extends Sprite{
public var boards:Array = new Array();
private static const AMAUNT_BOARDS:uint = 6;
private static const NUMBER_FIELD_SIZE:uint = 20;
public function Main() {
for(var i:uint = 0; i < AMAUNT_BOARDS; i++)
{
var numbers:Array = genNumbers();
numbers = deleteFields(numbers);
var board:Sprite = getBoard(numbers);
board.y = NUMBER_FIELD_SIZE * 4 * i;
boards.push(board);
addChild(board);
}
}
//generates a 2 Dimensional Array (3x9) with TextFields
//populates the according Numbers and returns a board Sprite
private function getBoard(n:Array):Sprite
{
var s:Sprite = new Sprite();
var a:Array = new Array();
for(var i:uint = 0; i < 3; i++)
{
var b:Array = new Array();
for(var k:uint = 0; k < 9; k++)
{
//create TextFields
var tf:TextField = new TextField();
tf.x = k * NUMBER_FIELD_SIZE;
tf.y = i * NUMBER_FIELD_SIZE;
tf.border = true;
tf.width = NUMBER_FIELD_SIZE;
tf.height = NUMBER_FIELD_SIZE;
if(n[k][i] != 0) // adds the number if the value isn't 0
tf.text = n[k][i]; // Note that i am switching k & i because the number Array is 9x3
b.push(tf);
s.addChild(tf);
}
}
return s;
}
// Turns 4 random numbers out of the lines into 0 And returns the Array
private function deleteFields(a:Array):Array
{
for(var i:uint = 0; i < 3; i++)
{
var r:RandomPlus = new RandomPlus(8,0);
for(var k:uint = 0; k < 4; k++)
{
var t:uint = r.getNum();
a[t][i] = 0;
}
}
return a;
}
// Generates and returns a 2 Dimensional Array (9x3) with random numbers
private function genNumbers():Array
{
var a:Array = new Array();
var st:uint = 1;
var en:uint = 9;
for(var i:uint = 0; i < 9; i++)
{
var line:Array = new Array();
var ran:RandomPlus = new RandomPlus(en,st);
if(i == 0)//accounting for the number differnenz at start
st--;
if(i==7)//accounting for the number differnenz at end
en ++;
st += 10;
en += 10;
for(var e:uint = 0; e < 3; e++)
line[e] = ran.getNum();
a.push(line);
}
return a;
}
}
}
TL;DR: "Main" in the class definition may have to be changed conflict of already existing name. Extends sprite may need to be changed to extends movieclip. RandomPlus either needs an import you don't have or needs to be made into a symbol and exported to Actionscript.
Ok, so a few things:
If you are really putting the code into the stage code area, then you can't use the private identifier.
Unless RandomPlus is an object that you have defined in the stage it is probably either not a method you can use or you don't have the right imports for it. Look up what imports you need for RandomPlus or if it is an object defined in the stage then you may need to turn it into a symbol or if you have already export it to flash ActionScript I think. To do this you have to check the checkbox in the middle of the symbol creation page. It will always give you the error when you do this, but don't worry it is fine that way.
Third thing is that I never extend sprite in the class definition, I always do extends movieclip(not sure of the capitalization, but you can look that up). You may also be running into an error from using "Main" as the name because it may be a conflict with a name or method already defined in flash in general.
One last thing is for the variable declaration(mostly just for making the code more readable). While it is good to not declare variables as global when you don't have to, I tend to like having most of the variables up at the top, because I like to be able to see most of the declarations in one space. It's not necessary, really just a personal opinion, and I know a lot of experienced coders will say to do what you did, but if you want to use the arrays in multiple functions then sometimes it is easier to just declare them globally rather than having to pass a million things in the function call and then having to figure out later where all the variable declarations are called and where they are being passed as arguments. Again it's more of a coder's choice, but you can also just do whatever you feel more comfortable with rather than just following the already laid out rules by people who have more experience coding.
Another optional fix to the organization might be to name variables something meaningful so as to not forget what they are all doing. I am bad at naming as well, but I think it's really better to name them something better than just a single letter or two.
Another thing that can help is placing trace(code or "text"); in different places to see what's going wrong once you have the compiler happy.

Is it faster to set a reference to a local variable of a nested object in ActionScript or the same?

I have an object that is nested several levels deep which I'm referencing multiple times. Is it faster to create and set a reference to that object or does it matter?
Context
I heard that it is faster to create a local reference. This is years ago and for a Visual Basic project. But this is Flash. And the output is a SWF / bytecode. And the compiler could look at that reference and do what I'm doing so that the object does not have to be looked up each time.
For example:
public function doStuff():void {
Model.instance.view1.button1 = button1;
Model.instance.view1.button2 = button2;
Model.instance.view1.button3 = button3;
Model.instance.view1.button4 = button4;
Model.instance.view1.button5 = button5;
Model.instance.view1.button6 = button6;
// more fake code referencing more something.something.something like things
for (var i:int;i<something.something.something.length;i++) {
var result:Object = Controller.staticMethod(button1);
var result2:Object = Controller.staticMethod(button1);
}
}
Vs:
public function doStuff():void {
var view1:View = Model.instance.view1;
view1.button1 = button1;
view1.button2 = button2;
view1.button3 = button3;
view1.button4 = button4;
view1.button5 = button5;
view1.button6 = button6;
}
.
Taking Baris suggestion I tested it for myself. Below are the results (though I don't know how to interpret them into the actual difference ie 'method 1 is .000001 faster than method 2').
Results
Test 1
var instance:Model = Model.instance;
var startTime:int = getTimer();
for(var i:int = 0; i<10000000; i++){
instance.url = "";
}
trace(getTimer()-startTime); // 826, 929, 823
var startTime:int = getTimer();
for(var i:int = 0; i<10000000; i++){
Model.instance.url = "";
}
trace(getTimer()-startTime); // 3483, 3976, 3539
Test 2
var instance:Model = Model.instance;
var localLogo:BitmapImage = Model.instance.logo;
var startTime:int = getTimer();
for(var i:int = 0; i<10000000; i++){
localLogo = logo;
}
trace(getTimer()-startTime); // 2070, 2083, 2110
var startTime:int = getTimer();
for(var i:int = 0; i<10000000; i++){
instance.logo = logo;
}
trace(getTimer()-startTime); // 2028, 2509, 2154
Generally, the as3 compiler is not that smart as we think. I think it does that to reduce compilation times.
This page http://upshots.org/actionscript/20-tips-to-optimize-your-actionscript gives us a rule:
5: The one-dot rule When accessing nested variables, anytime a
variable requires even one level of scope shift to discover, and is
referenced more than once, save it to local variable. In drawing
classes, you’ll often see Math.PI / 2 referenced within loops that
might iterated hundreds of times each frame – that value should be
stored in a local variable. Note that this is not true when
referencing member methods. Saving Math.PI to a variable is
appropriate; saving Math.round to a variable is not.
It does make difference, but to a software building perspective, the more readable code would be the propper way to do it, unless it's critical code, like a physics section of your app.
Other than making time benchmarks, you can inspect the bytecode too, using this tool http://www.swfwire.com/
I prefer :
public function doStuff():void {
var view1:View = Model.instance.view1;
view1.button1 = button1;
view1.button2 = button2;
view1.button3 = button3;
view1.button4 = button4;
view1.button5 = button5;
view1.button6 = button6;
}
I think it looks cleaner, you can profile and see which one is faster but it won't matter performance wise if you are not doing this tons of times in some inner loop.
public function doStuff():void {
var startTime:int = getTimer();
for(var i:int = 0; i<1000000; i++){
Model.instance.view1.button1 = button1;
Model.instance.view1.button2 = button2;
Model.instance.view1.button3 = button3;
Model.instance.view1.button4 = button4;
Model.instance.view1.button5 = button5;
Model.instance.view1.button6 = button6;
}
trace(getTimer()-startTime);
}
public function doStuff():void {
var startTime:int = getTimer();
for(var i:int = 0; i<1000000; i++){
var view1:View = Model.instance.view1;
view1.button1 = button1;
view1.button2 = button2;
view1.button3 = button3;
view1.button4 = button4;
view1.button5 = button5;
view1.button6 = button6;
}
trace(getTimer()-startTime);
}
The time to access is probably irrelevant, because you seem to be doing some UI work, and fractions of milliseconds it will take are of no concern. There are other concerns though:
You are writing repetitious code - this is bad, always. If it must be repeated, you should write a program that repeats it from a single source everywhere, if it may not be repeated - opt not to repeat. The concern is simple. Once you discover that the buttons are in ModelB.instance.view1 you will need to copy and paste the same code multiple times - of course while doing repetitive work you will make a mistake.
AS3 code not only allows, it also welcomes side effects, which, in this case may create undesirable effect. For example, Model.instance.view1 may be a getter that returns a new copy of view every time it is accessed, or, when accessed, it may alter something else in the internal state of the instance, whatever that is, and performing this change multiple times is undesirable.
There's Demeter's rule. When simplified beyond possible, it says that you shouldn't use more than a single dot operator in succession. I.e. an object may only be aware of the property of its own property (or local variable), but never access the property of the property of the property and never further down the line. This imposes unnecessary restriction on the structure of your program. However, sometimes it looks like it might be difficult to avoid, you should strive for a better, self-contained code. More on Demeter's rule here: http://en.wikipedia.org/wiki/Law_of_Demeter
It is not a function of compiler to "optimize" such code, especially because of the side effects. Compiler will faithfully follow the bad code written by a programmer and generate a lot of repetitious assembly because it trusts the programmer that this code is actually needed. Note, I'm not talking about Adobe compiler, which is not an optimizing compiler, and wouldn't remove this code even if the static analysis suggested that. I'm talking about some abstract "ideal" compiler for the language, that would optimally compile the code in question.

Using . or [ ] to access Object properties - what's the difference?

What is the difference between the code (i) and (ii) written below ?
(i)
var obj:Object = new Object();
obj.attribute = value ;
(ii)
var obj:Object = new Object();
obj["key"] = value;
Are there any run-time implications if I write this :
var obj:Object = new Object();
obj.somekey = value1 ;
obj["someKey"] = value2 ;
Please explain.
The difference is in the lookup mechanism: If you use the dot syntax, the compiler will know at compile time that you are accessing a property of that object. If you use the bracket syntax, the actual lookup of the property is done at runtime, and there will have to be more type checking - after all, you could compose the key string dynamically, the value could change, or you could even be calling a function instead of a variable, etc.
The result is a significant difference in performance: Bracket syntax takes about three times as long to execute as dot syntax.
Here's a little speed test to illustrate my point:
var start : int = getTimer();
var obj:Object = { something : "something" };
for (var i : int = 0; i < 100000000; i++) {
var n:String = obj.something;
}
trace ("Time with dot syntax: "+(getTimer() - start));
start = getTimer();
for (i = 0; i < 100000000; i++) {
var o:String = obj["something"];
}
trace ("Time with bracket syntax: "+(getTimer() - start));
If the two were the same, except for notation, they should take exactly the same amount of time. But as you can see, this is not the case. On my machine:
Time with dot syntax: 3937
Time with bracket syntax: 9857

Is ActionScript 3 Dictionary a hashmap?

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/
The dictionary does what I need but I do need to care about performance. Does anybody know if the Dictionary is implemented as a hashtable?
Or more specifically, does it perform in O(1)?
it acts as a hashmap. in fact, every ActionScript object that is an instance of a dynamic class, acts as hashmap. of course keys can always collide with properties. this behaviour comes from JavaScript. I consider it a design failure.
Array is different in that it will perform some tricks on integer keys, and Dictionary is different in that it doesn't convert keys to strings, but uses any object value as key. Please note that Number and Boolean are both converted to String.
now why whould you care how it is implemented? if it is well implemented, you probably don't wanna know. You can benchmark it. It has O(1) for all operations and is reasonably fast (inserting costs a about twice as much time as an empty method call, deleting costs less). Any alternative implementation will be slower.
here a simple benchmark (be sure to compile it for release and run it in the right player):
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.*;
public class Benchmark extends Sprite {
public function Benchmark() {
var txt:TextField = new TextField();
this.addChild(txt);
txt.text = "waiting ...";
txt.width = 600;
const repeat:int = 20;
const count:int = 100000;
var d:Dictionary = new Dictionary();
var j:int, i:int;
var keys:Array = [];
for (j = 0; j < repeat * count; j++) {
keys[j] = { k:j };
}
setTimeout(function ():void {
var idx:int = 0;
var out:Array = [];
for (j = 0; j < repeat; j++) {
var start:int = getTimer();
for (i = 0; i < count; i++) {
d[keys[idx++]] = i;
}
out.push(getTimer() - start);
}
txt.appendText("\n" + out);
start = getTimer();
for (var k:int = 0; k < i; k++) {
test();
}
txt.appendText("\ncall:"+(getTimer() - start));
idx = 0;
out = [];
for (j = 0; j < repeat; j++) {
start = getTimer();
i = 0;
for (i = 0; i < count; i++) {
delete d[keys[idx++]];
}
out.push(getTimer() - start);
}
txt.appendText("\n" + out);
},3000);//wait for player to warm up a little
}
private function test():void {}
}
}
Nope, it's not. java hashmaps are based on hash codes, while Dictionary is based on strict equality (===) of keys and therefore must not be used if you plan to put objects as keys.
java:
class MyStuff {
public final int id;
MyStuff(int i) {
this.id = i;
}
public int hashCode() {
return this.id;
}
public int equals(MyStuff o) {
return (this.id - o.id);
}
}
Map<MyStuff, Object> m1 = new HashMap<MyStuff, Object>();
m1.put(new MyStuff(1), new Object());
assert(m1.get(new MyStuff(1)) != null); //true
as3:
class MyStuff {
public var id:Number;
public function MyStuff(i:Number):void {
this.id = i;
}
//no notion of hashCode or equals in AS3 Object class,
//so we can't really control how the Objects are compared.
}
var d:Dictionary = new Dictionary();
d[new MyStuff(1)] = {};
trace(d[new MyStuff(1)]); //outputs null
I'm looking into the right way of implementing hashing in AS3, but it does look very unpromising...
The adobe documentation on associate arrays seems to imply that dictionaries are hashmaps:
"You can use the Dictionary class to create an associative array that uses objects for keys rather than strings. Such arrays are sometimes called dictionaries, hashes, or maps."
http://livedocs.adobe.com/flex/3/html/help.html?content=10_Lists_of_data_4.html