Protected: n24.de: Was würdet ihr tun?”, Provokante Fragen an die muslimische Welt

This content is password protected. To view it please enter your password below:

Advertisements

springrts.com: Lua Performance

springrts.com: Lua Performance

About Games Development Media Help Forums Wiki Report a bug Download
Lua Performance
Contents [hide]
1 Overview
2 Other Considerations
3 Performance Tests
3.1 TEST 1: Localize
3.2 TEST 2: Localized Class-Methods (with only 3 accesses!)
3.3 TEST 3: Unpack A Table
3.4 TEST 4: Determine Maximum And Set It (‘>’ vs. max)
3.5 TEST 5: Nil Checks (‘if’ vs. ‘or’)
3.6 TEST 6: ‘x^2’ vs. ‘x*x’
3.7 TEST 7: Modulus Operators (math.mod vs. %)
3.8 TEST 8: Functions As Param For Other Functions
3.9 TEST 9: for-loops
3.10 TEST 10: Array Access (with [ ]) vs. Object Access (with .method)
3.11 TEST 11: Buffered Table Item Access
3.12 TEST 12: Adding Table Items (table.insert vs. [ ])
3.13 TEST 12: Adding Table Items (mytable ={} vs. mytable={…})
4 Lua Garbage Collection
Overview
This page is copied from the CA wiki. The widget used in the performance tests is available from the CA SVN.
Other Considerations
It is a well known axiom in computing that
“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”
– Donald Knuth
Lua coders should keep that in mind, and especially when visiting this page. Readability and maintainability are in most cases just as important, and optimizing code for every last ounce of performance can severely impact those qualities. On the other hand, some of the optimizations suggested have little bearing on readability and should generally always be applied, e.g. localization of API functions, or actually make for neater code e.g. the use of or rather than a nil-check. Generally speaking, optimize only once you are sure that there is or will be a performance bottleneck.
Performance Tests
TEST 1: Localize
Code:
local min = math.min

Results:
Non-local: 0.719 (158%)
Localized: 0.453 (100%)
Conclusion:
Yes, we should localize all standard lua and Spring API functions.

TEST 2: Localized Class-Methods (with only 3 accesses!)
Code 1:
for i=1,1000000 do
local x = class.test()
local y = class.test()
local z = class.test()
end

Code 2:
for i=1,1000000 do
local test = class.test
local x = test()
local y = test()
local z = test()
end

Results:
Normal way: 1.203 (102%)
Localized: 1.172 (100%)
Conclusion:
No, it isn’t faster to localize a class method IN the function call.

TEST 3: Unpack A Table
Code 1:
for i=1,1000000 do
local x = min( a[1],a[2],a[3],a[4] )
end

Code 2:
local unpack = unpack
for i=1,1000000 do
local x = min( unpack(a) )
end

Code 3:
local function unpack4(a)
return a[1],a[2],a[3],a[4]
end
for i=1,1000000 do
local x = min( unpack4(a) )
end

Results:
with [ ]: 0.485 (100%)
unpack(): 1.093 (225%)
custom unpack4: 0.641 (131%)
Conclusion:
Don’t use unpack() in time critical code!

TEST 4: Determine Maximum And Set It (‘>’ vs. max)
Code 1:
local max = math.max
for i=1,1000000 do
x = max(random(cnt),x)
end

Code 2:
for i=1,1000000 do
local r = random(cnt)
if (r>x) then x = r end
end

Results:
math.max: 0.437 (156%)
‘if > then’: 0.282 (100%)
Conclusion:
Don’t use math.[max|min]() in time critical code!

TEST 5: Nil Checks (‘if’ vs. ‘or’)
Code 1:
for i=1,1000000 do
local y,x
if (random()>0.5) then y=1 end
if (y==nil) then x=1 else x=y end
end

Code 2:
for i=1,1000000 do
local y
if (random()>0.5) then y=1 end
local x=y or 1
end

Results:
nil-check: 0.297 (106%)
a=x or y: 0.281 (100%)
Conclusion:
The or-operator is faster than a nil-check. Use it!

TEST 6: ‘x^2’ vs. ‘x*x’
Code 1:
for i=1,1000000 do
local y = x^2
end

Code 2:
for i=1,1000000 do
local y = x*x
end

Results:
x^2: 1.422 (110%)
x*x: 1.297 (100%)
Conclusion:
The second syntax is marginally faster

TEST 7: Modulus Operators (math.mod vs. %)
Code 1:
local fmod = math.fmod
for i=1,1000000 do
if (fmod(i,30)<1) then
local x = 1
end
end

Code 2:
for i=1,1000000 do
if ((i%30)<1) then
local x = 1
end
end

Results:
math.mod: 0.281 (355%)
%: 0.079 (100%)
Conclusion:
Don't use math.fmod() for positive numbers (for negative ones % and fmod() have different results!)

TEST 8: Functions As Param For Other Functions
Code 1:
local func1 = function(a,b,func)
return func(a+b)
end

for i=1,1000000 do
local x = func1(1,2,function(a) return a*2 end)
end

Code 2:
local func1 = function(a,b,func)
return func(a+b)
end
local func2 = function(a)
return a*2
end

for i=1,1000000 do
local x = func1(1,2,func2)
end

Results:
defined in function param: 3.890 (1144%)
defined as local: 0.344 (100%)
Conclusion:
REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!! i.e if you use gl.BeginEnd(), gl.CreateList(), …!!!

TEST 9: for-loops
Code 1:
for i=1,1000000 do
for j,v in pairs(a) do
x=v
end
end

Code 2:
for i=1,1000000 do
for j,v in ipairs(a) do
x=v
end
end

Code 3:
for i=1,1000000 do
for i=1,100 do
x=a[i]
end
end

Code 4:
for i=1,1000000 do
for i=1,#a do
x=a[i]
end
end

Code 5:
for i=1,1000000 do
local length = #a
for i=1,length do
x=a[i]
end
end

Results:
pairs: 3.078 (217%)
ipairs: 3.344 (236%)
for i=1,x do: 1.422 (100%)
for i=1,#atable do 1.422 (100%)
for i=1,atable_length do: 1.562 (110%)
Conclusion:
Don't use pairs() or ipairs() in critical code! Try to save the table-size somewhere and use for i=1,x do!

TEST 10: Array Access (with [ ]) vs. Object Access (with .method)
Code 1:
for i=1,1000000 do
x = a["foo"]
end

Code 2:
for i=1,1000000 do
x = a.foo
end

Results:
atable["foo"]: 1.125 (100%)
atable.foo: 1.141 (101%)
Conclusion:
No difference.

TEST 11: Buffered Table Item Access
Code 1:
for i=1,1000000 do
for n=1,100 do
a[n].x=a[n].x+1
end
end

Code 2:
for i=1,1000000 do
for n=1,100 do
local y = a[n]
y.x=y.x+1
end
end

Results:
'a[n].x=a[n].x+1': 1.453 (127%)
'local y=a[n]; y.x=y.x+1': 1.140 (100%)
Conclusion:
Buffering can speed up table item access.

TEST 12: Adding Table Items (table.insert vs. [ ])
Code 1:
local tinsert = table.insert
for i=1,1000000 do
tinsert(a,i)
end

Code 2:
for i=1,1000000 do
a[i]=i
end

Code 3:
for i=1,1000000 do
a[#a+1]=i
end

Code 4:
local count = 1
for i=1,1000000 do
d[count]=i
count=count+1
end

Results:
table.insert: 1.250 (727%)
a[i]: 0.172 (100%)
a[#a+1]=x: 0.453 (263%)
a[count++]=x: 0.203 (118%)
Conclusion:
Don't use table.insert!!! Try to save the table-size somewhere and use a[count+1]=x!

TEST 12: Adding Table Items (mytable ={} vs. mytable={…})
When you write {true, true, true} , Lua knows beforehand that the table will need three slots in its array part, so Lua creates the table with that size. Similarly, if you write {x = 1, y = 2, z = 3}, Lua will create a table with four slots in its hash part.
As an example, the next loop runs in 2.0 seconds:

for i = 1, 1000000 do
local a = {}
a[1] = 1; a[2] = 2; a[3] = 3
end
If we create the tables with the right size, we reduce the run t ime to 0.7 seconds:
for i = 1, 1000000 do
local a = {true, true, true}
a[1] = 1; a[2] = 2; a[3] = 3
end
If you write something like {[1] = true, [2] = true, [3] = true}, however, Lua is not smart enough to detect that the given expressions (literal numbers, in this case) describe array indices, so it creates a table with four slots in its hash part, wasting memory and CPU time

China Shops Kleidung, Handys und Tablets zum Schnäppchenpreis

China Shops Kleidung, Handys und Tablets zum Schnäppchenpreis

Chinesische Onlineshops finden sich immer häufiger in den Suchergebnissen bei Google, dennoch begegnen viele ihnen mit eine gewissen Skepsis. Zu Unrecht, denn die Zeiten in denen chinesische Händler vor allem durch Produktfälschungen auf sich aufmerksam machten, sind vorbei. Stattdessen bieten die Internet Kaufhäuser aus China heute asiatische Markenware an, die sich was die Qualität angeht nicht hinter Produkten aus Deutschland, Europa oder den USA verstecken müssen. Das viele international bekannte Marken ihre Waren in China fertigen lassen und dann im eigenen Namen mit riesigen Gewinnspannen verkaufen, ist ein offenes Geheimnis.

Ein gutes Beispiel ist der deutsche Schuhhandel, der alleine 2013 fast 300 Millionen Paar Schuhe auf China importiert und mit einer durchschnittlichen Rendite von satten 47% weiterverkauft hat, siehe http://de.statista.com/themen/158/schuhhandel-in-deutschland/ Nicht anders bei Elektronik, hier liegen die Spannen teils noch wesentlich höher. Solche Zahlen veranschaulichen auch, wie viel sich beim Direktimport, als der Bestellung direkt in China, an Geld sparen lässt.

Wir beantworten die häufigsten Fragen rund um Shopping in China, geben Tipps aus der Praxis und zeigen Ihnen, bei welchen chinesischen Onlineshops Sie aus unserer eigenen Erfahrung bedenkenlos einkaufen können.

A DNA-based archival storage system

the morning paper

A DNA-Based Archival Storage System – Bornholt et al. ASPLOS ’16

It’s pretty cool that a paper on DNA-based storage makes a conference such as ASPLOS. And as you’ll see, there are good reasons we should be taking it very seriously indeed. DNA has some very interesting properties – it’s extremely dense (1 exabyte (109 GB) per mm3) and lasts a long-time (observed. half-life of over 500 years. It doesn’t work quite like this, but to put that density into context, imagine how many mm3 of raw storage you could fit into a USB-sized form factor. I’ll guess at least 100 – that would be 100,000 PB of storage in your thumb-drive!

In this paper the authors build a DNA-based key-value store supporting random access and are successfully able to store and retrieve data. Crucially, it seems that the internet’s cute kitten image archive can be…

View original post 1,531 more words

codeproject.com: The Ultimate Grid Home Page

codeproject.com: The Ultimate Grid Home Page

We are very happy to announce that we have made the decision to offer our commercial lineup of MFC libraries, including Ultimate Toolbox, Ultimate Grid, and Ultimate TCP/IP to the CodeProject.com community free of charge.

These are the full and complete libraries including source code, documentation, samples and examples.

Ultimate Toolbox, Ultimate Grid and Ultimate TCP/IP come with full source code, and are compatible with Microsoft Visual Studio versions 6.0 through 2005.

The Ultimate Toolbox and line of related MFC libraries products have been powering professional MFC applications for more than 10 years. We realize that there is a very large number of users who are still coding new applications in Visual C++ and MFC and who are looking for effective and proven libraries to enhance their applications, as well as those with legacy code to maintain and update.

By releasing these long standing MFC libraries to the CodeProject.com community we hope that the libraries will continue to grow, evolve and provide a library of useful controls to the development community through the auspices of The Code Project and its members.

codeproject.com: Nish Nishant, MFC under the hood

codeproject.com: Nish Nishant, MFC under the hood

Most MFC/VC++ programmers generate their projects using App Wizard and are quite happy with that. Once in a while, you have a programmer who will ask you, what happened to WinMain and he is normally satisfied with the answer given that WinMain is hidden within the MFC libraries. In this article I’ll try and explain the life-cycle of a typical MFC program. Before I do that I’d like to introduce you to the smallest MFC program you can write that will show a window on screen, other than by using a MessageBox.

Smallest MFC window-program

//NWinApp.h
class CNWinApp  : public CWinApp
{
public:
    BOOL InitInstance();
};
Hide   Copy Code
//NWinApp.cpp
#include 
#include "NWinApp.h"

CNWinApp app;

BOOL CNWinApp::InitInstance()
{
    CFrameWnd *pnframe=new CFrameWnd;
    m_pMainWnd=pnframe;
    pnframe-&gt;Create(0,"Buster");
    pnframe-&gt;ShowWindow(SW_SHOW);
    return TRUE;
}

So, what happened to good old WinMain?
When you run your program the kernel first calls this function, WinMainCRTStartup. WinMainCRTStartup first initializes the CRT routines. Then it parses the command line and removes the filename portion and calls WinMain passing the parsed command line as lpszCommandLine. But then where is WinMain? Smile | 🙂 It is defined in appmodul.cpp which you can find in your MFC\SRC directory. Here is how the function is implemented.

extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine, int nCmdShow)
{
    // call shared/exported WinMain
    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}

As you will observe, WinMain simply calls AfxWinMain. AfxWinMain is defined in winmain.cpp which you will find under your MFC\SRC directory. I’ll list the function below exactly as it is defined.

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine, int nCmdShow)
{
    ASSERT(hPrevInstance == NULL);

    int nReturnCode = -1;
    CWinThread* pThread = AfxGetThread();
    CWinApp* pApp = AfxGetApp();

    // AFX internal initialization
    if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
        goto InitFailure;

    // App global initializations (rare)
    if (pApp != NULL &amp;&amp; !pApp-&gt;InitApplication())
        goto InitFailure;

    // Perform specific initializations
    if (!pThread-&gt;InitInstance())
    {
        if (pThread-&gt;m_pMainWnd != NULL)
        {
            TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
            pThread-&gt;m_pMainWnd-&gt;DestroyWindow();
        }
        nReturnCode = pThread-&gt;ExitInstance();
        goto InitFailure;
    }
    nReturnCode = pThread-&gt;Run();

InitFailure:
#ifdef _DEBUG
    // Check for missing AfxLockTempMap calls
    if (AfxGetModuleThreadState()-&gt;m_nTempMapLock != 0)
    {
        TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
            AfxGetModuleThreadState()-&gt;m_nTempMapLock);
    }
    AfxLockTempMaps();
    AfxUnlockTempMaps(-1);
#endif

    AfxWinTerm();
    return nReturnCode;
}

As you can see the functions AfxGetThread and AfxGetApp are used to get pointers to the CWinApp derived global object and the current thread. If you are surprised as to how the global CWinApp derived object already exists, relax, C++ programs will first create all global and static objects before execution begins. All that happens much before AfxWinMain gets called. By the way, it must have been a slight shock to you to see a goto in there, eh?

Now there might be those of you who might be wondering where AfxGetThread and AfxGetApp got their information from. The answer is simple. Take a look at the CWinApp constructor in appcore.cpp. You’ll find the following two lines.

pThreadState-&gt;m_pCurrentWinThread = this;

and

pModuleState-&gt;m_pCurrentWinApp = this;
pThreadState is a AFX_MODULE_THREAD_STATE* and pModuleState is a AFX_MODULE_STATE*.

Thus when we create our global CNWinApp object, it’s constructor gets called and the AFX_MODULE_STATE structure is setup properly. Now AfxWinInit is called and this function initializes the MFC framework. Now there is a call to InitApplication [this is for backward compatibility with 16-bit applications]. Now it calls the InitInstance of the CWinApp derived object. And as you can see from our code listing above we have overridden InitInstance and created a CFrameWnd object there. I’ll repeat the code snippet here so that you won’t have to scroll upwards.

BOOL CNWinApp::InitInstance()
{
    CFrameWnd *pnframe=new CFrameWnd;
    m_pMainWnd=pnframe;
    pnframe-&gt;Create(0,"Buster");
    pnframe-&gt;ShowWindow(SW_SHOW);
    return TRUE;
}

I have created my CFrameWnd object on the heap, otherwise the moment InitInstance exits, the window will get destroyed. I have also set m_pMainWnd to point to my CFrameWnd window. Once InitInstance returns [if it returns false an error is assumed, so we return true], CWinApp::Run is called. Within the Run function is implemented our default message loop. Run keeps getting and dispatching messages till it receives a WM_QUIT message. Once WM_QUIT is received Run returns and control returns to AfxWinMain which performs clean-up and lastly calls AfxWinTerm which deletes all the global application structures that were created.

Well, that’s it. Pretty amusing to think that all this while you were writing MFC applications and you never bothered to think about what was happening under the hood.

DISCLAIMER
None of the information in this article is endorsed by me. I don’t work for Microsoft and all my assumptions are just that – assumptions. Some of the info I have given might indeed be incorrect, though I’d say the probability for that is rather low. In case I have erred I’ll be delighted if someone can correct those mistakes.

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)