| 04-21-2009, 01:10 PM | #1 |
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 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: 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 |
| 04-21-2009, 03:22 PM | #2 | |||
Quote:
Quote:
ps. at last oplimit counter used to detect "more efficient code" pps. Quote:
|
| 04-21-2009, 06:26 PM | #3 |
Sorry, I didn't really understand your post.. What's your point? |
| 04-22-2009, 08:14 PM | #4 |
Update. |
| 04-23-2009, 01:03 AM | #5 |
How can it detect typos exactly.. that just seems a little bit impossible to me |
| 04-23-2009, 04:17 AM | #6 |
afaik it can detect typos ...but only for the user interface of the system itself ... |
| 04-23-2009, 04:50 AM | #7 |
test something with this and post results. then test same code by stopwatch. have some fun. |
| 04-23-2009, 05:42 AM | #8 | |
what does this even do? Quote:
|
| 04-23-2009, 12:55 PM | #9 |
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: 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: 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: 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: 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: |
| 05-04-2009, 08:03 AM | #10 |
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 |
redundant escalope !!! |
| 05-04-2009, 11:13 AM | #12 | |
Quote:
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 |
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 |
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 |
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. |
