HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Emmeasure?

04-21-2009, 01:10 PM#1
Mr.Malte
Emmeasure...
Emmeasure is a part of the Em collection (I'll release the Emcollection soon).
Emmeasure is the most comfortable Test System I know.
Emmeasure is used to test, how fast systems/functions are.

Features...
Emmeasure can find typos
You can inline the Emmeasure code into a library
After the test, you can show the result prettily.
Emmeasure compares the systems speeds.
Emmeasure is idiotic safe.
Emmeasure has clear error messages
Struct Iterating, KT, TT, PUI, HandleIndexing, TimerUtils and HSAS are already prepared to test

Highly recommended...
To download the test map ! It contains a lot more stuff

Requires...
Grimoire

Descripotion
Collapse JASS:
//*********************************************************************
//* Emmeasure
//* ----------
//*
//*
//* To implement it , create a custom text trigger called Embasic
//* and paste the contents of this script there.
//* If you want to use it, don't forget to call InitEmbasic() at the map start.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
// ======= What is Emmeasure ? =======
// Emmeasure is a system that is used to test how fast other systems are.
//
// ======= Functions of Emmeasure =======
// Test.Declare(string)                : Declares a system name that you want to test.
// Test.Start(sys,string)              : Starts a Test call for a system.
// Test.End()                          : Ends the Test.
// Test.Display(sysname)               : Displays, how well a system performed.
// Test.Compare()                      : Compares all Systems and Displays which ones are the fastest.
// Test.RegisterInstance(sysname)      : Registers, that a new instance of the test has started.
// Test.RemoveInstance(sysname)        : Removes a registered Instance.
// Test.RunThisCode(sysname)           : Returns, if the system has exactly one registered Instance.
// Test.RunCode()                      : Displays if no System Instances are running.
// Test.DisplayErrors()                : Displays all errors.

// ======= Test correctly =======
// This is extremely safe, you can't do much wrong.
// With this test System you should insert the Test functions Start and End directly into the code.
// Typos are recognized and cleared.
//*
//********************************************************************
library Emmeasure initializer Init
    //!             === DISABLE_ERROR ===
    // This messages will be displayed, if Emmeasure was disabled, because it hasn't been used
    // properly.
    //!             === ABORT_ERROR ===
    // This message will be displayed, if a Benchmark was aborted, because it hasn't been used
    // properly.
    //!             === COLOR_MASSIVELY ===
    // Changes the Color Algorithm, so if this is true, the Colors are more glaring and you can
    // see the speed differnces clearly. [Read PF 1]
    //!             === UNIQUE_ERRORS ===
    // If this is true, the system will not spam error messages, it will display each unique message
    // once. Example: It will not display 'I am nobus m' twice, even if the error appears 100 times or more.
    // [ Read PF 2 ]
    //!             === DETECT_TYPOS ===
    // If this option is set to true, the system will detect Typos. For Example: 
    // You registered the System 'TimerUtils', but you write Test.Start("TimerUils","NewTimer")
    // TimerUils is registered as a typo then, because it is very similar to TimerUtils.
    // This can not detect Typos from things with less than 4 letters, because the chance would be
    // too high to randomly add the Time to another System. If you don't care, change TYPO_MIN_MATCH
    // to a percentage value the strings should mathc exactly. [ Read PF 2 ]
    //!             === DISPLAY_TYPOS ===
    // If this option is set to true and DETECT TYPOS is true, too, the system displays where you made Typos.
    //!             === QUALITY ===
    // This shouldn't be changed in order to make tests more uniform. I think I'll add a protection later, so
    // that people can't cheat.
    // What it does? It Displays how good the test has been at the End.
    // If you tested 30 000 times for example, it would display 'safe'.
    // And if you test 500 times, it would display 'unacceptable'.

    //!             === [PF 1] ===
    // Performance Cost 1: The system itself gets a tiny little bit slower, so it might lag more, but this doesn't affect
    // the speed of other systems.
    //!             === [PF 2] ===
    // Performance Cost 2: The system itself gets a little bit slower, so it might lag more, but this doesn't affect
    // the speed of other systems.
    //! ============= Thanks to =============
    // - Mastaofpuppets for chiffring function
    // - Buster4 for Per2Clr and Int2Hex
    // - XieLong for a bit help with the colorcode algorithms.
    // - Vexorian for JassNewgNen
    globals  
        private constant string DISABLE_ERROR    =  "Emmeasure was Disabled."
        private constant string ABORT_ERROR      =  "Aborting Benchmark!"
        private constant boolean COLOR_MASSIVELY =  true
        private constant boolean UNIQUE_ERRORS   =  true
        private constant boolean DETECT_TYPOS    =  true
        private constant boolean DISPLAY_TYPOS   =  true
        private constant real TYPO_MIN_MATCH     =  67. // Do not change!
        private constant integer QUALITY         =  6000 // Do not change!
    endglobals

Example:
Collapse JASS:
library StructIterating initializer Init requires b
    globals
        timer Ex = CreateTimer()
        private What array WhatData
        private integer count = 0
        private boolean First = true
    endglobals

struct What
    string wtf
    integer bla

    method ClearInstance takes integer iterator returns nothing
        call WhatData[iterator].destroy()
        set WhatData[iterator] = WhatData[count]
        set count = count - 1
    endmethod

    static method NewInstance takes nothing returns What
        local What w = What.create()
        set count = count + 1
        set WhatData[count] = w
        return w
    endmethod
endstruct

public function Loop takes nothing returns nothing
    local integer i = 0
    local What temp
    call Test.Start("Struct Iterating","Loop")
    loop
        set i = i + 1
        exitwhen i > count
        set temp = WhatData[i]
        // Do whatever you want.

        set temp.bla = temp.bla + 1
        if temp.bla > Executions then
            call temp.ClearInstance(i)
            set Ended = Ended + 1
            call BJDebugMsg("Instance ended; "+I2S(Ended))

            call Test.End()
            if Test.RunThisCode("Struct Iterating") then
                call PauseTimer(Ex)
            endif
            call Test.RemoveInstance("Struct Iterating")

            if Test.RunCode() then
                call Test.Compare()
           else
                call Test.Start("Struct Iterating","Loop")
            endif
            
        endif

    endloop
    call Test.End()
endfunction

public function InsertData takes nothing returns nothing
    call Test.RegisterInstance("Struct Iterating")
    call What.NewInstance()
    if Test.RunThisCode("Struct Iterating") then
        call TimerStart(Ex,(1./FPS),true,function StructIterating_Loop)
    endif
endfunction

private function Init takes nothing returns nothing
    if StructIterating == true and TEST_LOW_PERIOD then
        call Test.Declare("Struct Iterating",0)
    endif
endfunction
endlibrary

Code
http://peeeq.de/code.php?id=1711
Attached Files
File type: w3xEmmeral Collection v1.00.w3x (137.1 KB)
04-21-2009, 03:22 PM#2
DioD
Quote:
Emmeasure is used to test, how fast systems/functions are.
holysh!!111one you did it 6years passed i wait soo long.

Quote:
set StableWord[0] = Per2Clr("unacceptable",100,0,0,0)
set StableWord[1] = Per2Clr("poor",86,14,0,0)
set StableWord[2] = Per2Clr("lacking",71,28,0,0)
set StableWord[3] = Per2Clr("not bad",100,100,0,0)
set StableWord[4] = Per2Clr("fine",45,70,0,0)
set StableWord[5] = Per2Clr("safe",30,80,0,0)
set StableWord[6] = Per2Clr("Great",20,80,0,0)
set StableWord[7] = Per2Clr("Excellent",0,100,0,0)
Divine values without proof

ps. at last oplimit counter used to detect "more efficient code"

pps.
Quote:
Emmeasure can find typos
rofl
04-21-2009, 06:26 PM#3
Mr.Malte
Sorry, I didn't really understand your post..
What's your point?
04-22-2009, 08:14 PM#4
Mr.Malte
Update.
04-23-2009, 01:03 AM#5
Avenger
How can it detect typos exactly.. that just seems a little bit impossible to me
04-23-2009, 04:17 AM#6
akolyt0r
afaik it can detect typos ...but only for the user interface of the system itself ...
04-23-2009, 04:50 AM#7
DioD
test something with this and post results.

then test same code by stopwatch.

have some fun.
04-23-2009, 05:42 AM#8
Ammorth
what does this even do?

Quote:
Emmeasure is idiotic safe.
I'm majoring in engineering and I have no idea how to use your test map.
04-23-2009, 12:55 PM#9
Mr.Malte
Emmeasure has a big documentation (in the Emmeasure trigger).
When you're ingame, you have 2 units to click on.

It detects typos like this:
Collapse JASS:
function IsStringSimilarTo takes string a, string b, real percentage returns boolean
    local string tempa
    local string tempb
    local integer max = StringLength(a)+StringLength(b)
    local integer similar = 0
    loop
        exitwhen a == "" or b == ""
        set tempa = SubString(a,StringLength(a)-1,StringLength(a))
        set a = SubString(a,0,StringLength(a)-1)
        set tempb = SubString(b,StringLength(b)-1,StringLength(b))
        set b = SubString(b,0,StringLength(b)-1)
        if tempa == tempb then
            set similar = similar + 2
        else
            if StringLength(a) > StringLength(b) then
                set b = b+tempa
            elseif StringLength(b) > StringLength(a) then
                set a = a+tempb
            endif
        endif
    endloop
    if I2R(similar)/I2R(max) >= percentage*0.01 then
        return true
    endif
    return false
endfunction

If a system isn't registered
==> Loop through saved typos
==> Loop threough systems and check if the string names are similar.
==> Save typo



Test Comparison:
Let's say we want to test these two libraries:
Collapse JASS:
// Just random libraries, do not ever use, they're bullshit...
library FuncB
    globals
        private integer array ANum
        private integer AC = 0
    endglobals
    
    private function StringID takes string s returns integer
        return s
        return 0
    endfunction
    
    function FuncB takes unit who, string sys returns integer
        local integer i = 0
        local integer Get = StringID(GetUnitName(who)+sys)
        loop
            set i = i + 1
            exitwhen i > AC
            if Get == ANum[AC] then
                return i
            endif
        endloop
        
        set AC = AC + 1
        set ANum[AC] = Get
        return Get
    endfunction
endlibrary

library FuncA
    globals
        private handle array H
        private integer array Value
    endglobals
    
    private function H2I takes handle h returns integer
        return h
        return 0
    endfunction
    
    private function FreeSpace takes nothing returns integer
        local integer i = 0
        loop
            set i = i + 1
            exitwhen i > 8191
            if H[i] == null then
                return i
            endif
        endloop
        call BJDebugMsg("No free space")
        return 0
    endfunction
    
    function FuncA takes unit onWho, integer attach returns integer
        local integer UIndex = FreeSpace()
        set Value[UIndex] = attach
        return UIndex
    endfunction
    
    function FuncACLEAR takes handle onWho returns nothing
        local integer i = 0
        loop
            set i = i + 1
            exitwhen i > 8191
            if H[i] == onWho then
                set H[i] = null
                set Value[i] = 0
            endif
        endloop
        call BJDebugMsg("No free space")
        return
    endfunction
endlibrary

Ok. The libraries are bullshit, but we want to test their speed.
So with Emmeasure for example, you can't cause open threads and have additional comfort. It is safe, because the system detects many error types.

That's the direct code:
Collapse JASS:
library TestDirectSopWatch requires FuncA, FuncB, FuncC
    globals
        private real array Time
        private integer Watch
        private integer Executions = 0
        private integer Threads = 0
        private unit TestOn
        private constant integer MAX_EXECUTIONS = 0
        private constant integer MAX_THREADS = 0
    endglobals
    
private function test takes nothing returns nothing
    local real t0
    local real t1
    set Executions = Executions + 1
    if Executions > MAX_EXECUTIONS then
        set Executions = 0
        set Threads = Threads + 1
        call RemoveUnit(TestOn)
        set TestOn = CreateUnit(Player(0),'hpea',0,0,0)
        if Threads > MAX_THREADS then
            // Show Results
            call BJDebugMsg("Test A: "+R2S(Time[0]))
            call BJDebugMsg("Test B: "+R2S(Time[1]))
            call PauseTimer(GetExpiredTimer())
            call DestroyTimer(GetExpiredTimer())
        endif
    endif
    
    set t0 = StopWatchMark(Watch)
        call FuncA(TestOn,10)
        call FuncACLEAR(TestOn)
    set t1 = StopWatchMark(Watch)
    set Time[0] = Time[0] + (t1-t0)
    
    set t0 = StopWatchMark(Watch)
        call FuncB(TestOn)
    set t1 = StopWatchMark(Watch)
    set Time[1] = Time[1] + (t1-t0)
endfunction

struct Direct
    static method TestA takes nothing returns nothing
        set Watch = StopWatchCreate()
        local integer i = 0
        // Insert code to be benchmarked here
        call TimerStart(CreateTimer(),0.,true,function test)
    endmethod
endstruct

endlibrary

And that's the code with Emmeasure:
Collapse JASS:
library TestEmmeasure requires FuncA, FuncB
    globals
        private unit TestOn = null
    endglobals
    
private function test takes nothing returns nothing
    call TestHelper.NextInstance()
    
    if TestHelper.IsThreadNew() then
        call RemoveUnit(TestOn)
        set TestOn = CreateUnit(Player(0),'hpea',0,0,0)
    endif
    
    if TestHelper.IsFinished then
        call Test.Compare()
        return
    endif
    
    call Test.Start("FuncA","Main")
        call FuncA(TestOn,10)
        call FuncACLEAR(TestOn)
    call Test.End()
    
    
    call Test.Start("FuncB","Main")
        call FuncB(TestOn,"Blub")
    call Test.End()
    
endfunction

struct Em
    static method TestA takes nothing returns nothing
        call TestHelper.SetTest(250,250)
        call Test.Declare("FuncA",0)
        call Test.Declare("FuncB",0)
        call TimerStart(CreateTimer(),0.,true,function test)
    endmethod
endstruct

endlibrary

And Emmeasure is safer, and puts a sexy screen out:
Attached Images
File type: jpgTestEX.jpg (639.6 KB)
05-04-2009, 08:03 AM#10
Karawasa
This seems interesting but hasn't got much in the way of feedback. I hope this bump helps.
05-04-2009, 08:18 AM#11
akolyt0r
redundant escalope !!!
05-04-2009, 11:13 AM#12
Captain Griffen
Quote:
Originally Posted by DioD
test something with this and post results.

then test same code by stopwatch.

QFT.

No more discussion is at all needed until we have a variety of tests that put stopwatch against this for accuracy.
05-04-2009, 03:13 PM#13
Mr.Malte
Collapse JASS:
library Attach
    globals
        private constant integer SIZE = 8191
        private integer array ADat[SIZE]
        private constant integer SUBTRACT = 0x100000
    endglobals
    
function h2i takes handle h returns integer
    return h
    return 0
endfunction

    function Attach takes handle h, integer data returns nothing
        local integer Index = h2i(h)-SUBTRACT
        
        set data = data + 1
        if Index > SIZE then
            // It may be, that some handles will never be used.
            // When the handle ID gets too high, we use Places
            // that may be used, but if we've got luck, they aren't.
            if ADat[ModuloInteger(Index,SIZE)] != 0 then
                call BJDebugMsg("Attach: Overwrote data, because of too low size.")
                return
            endif
        endif
        
        set ADat[Index] = data
    endfunction
    
    function Get takes handle h returns integer
        local integer Index = h2i(h)-SUBTRACT
        return (ADat[Index]-1)
    endfunction
endlibrary

HandleIndexing vs. this library.
Tested 200*200 times.
StopWatch: ~53%
Emmeasure: ~54%
Both: HandleIndexing: Slower

Note, that there's always some variety.
Since I teted, noted the output, changed testing 'System' and noted again.

Do you want more tests?

Mine creates a table, a diagramm, calculates the percentage, is able to test different function speeds, is much more comfortable (TestHelper e.g)
and much more suited for noobs, because of protections for things like causing open threads. Also it displays errors nicely and each error once and detects typos.
05-04-2009, 04:16 PM#14
Captain Griffen
One test is really, really not enough. Remember you also need a variety of different types of function being tested. So say try testing an array lookup against GC lookup.
05-04-2009, 04:19 PM#15
Mr.Malte
Big Update!
Changes:

-You have two estimation units: CPF and EPF
-Fully implemented TestHelper. Supports timer and attaching systems well now.
-You can now measure the speed of single functions
-Added a 'Rate' - displays the importancy of a function for the test.
-Bettered the debug Help
-Added static method .createTable which creates an overview of the test.

Coming soon:
Assigning Dividend automatically.

NEW FEATURES
-Fully backwards compatible
-Functions are automatically assigned to systems.
-TestHelper

NOTE
-Systems can't be auto-registered. Ok, they can be, but you'll have a limti of about 100 systems, otherwise the 2dimensional Indexes for the Function assigns won't work
-I'll add watermarks soon that show if the test was cheated on
-I'll add a feature that compares how many times functions were called soon, in order to assign 'Dividend' automatically. But there are some complications
-New code here:
http://peeeq.de/code.php?id=1711
or in the first post.