forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   FAQ и уроки (http://forum.boolean.name/forumdisplay.php?f=110)
-   -   LinkedList (http://forum.boolean.name/showthread.php?t=3981)

jimon 22.07.2007 19:35

LinkedList
 
так ... :) сегодня посмотрим как еффективно его надо использовать

имеем такой вот тестик ...
Код:

'fucking linked list testing code
'by jimon lol :)

'create our MEEGA timer :)
Global Timer:TPerfCounter = TPerfCounter.Create(10000000)

'ok, create simple linked list
Global List:TList = New TList

'made some stupid type
Type testtype
        Field blablabla1% = 100
        Field blablabla2% = 200
        Field blablabla3% = 300
        Field blablabla4% = 400
End Type

'add 1000 copyes of this type to list
For Local i% = 0 To 1000
List.AddLast(New testtype)
Next

Global Count% = List.Count()-1

DebugLog "InitOk .. let's run" 'Lets some FUN !


'Test1 ... Fully compiler optimization for work with cycles
        DebugLog "Run Test1 ... the best optimization"
        Time1:Double = jMillisecs()

        'not hard cycle
        For Local t1:testtype = EachIn List
        t1.blablabla1 = 1
        Next

        Time1 = jMillisecs() - Time1
        DebugLog "Test1 Time : "+Time1
       
'Test2 ... this code maybe you can found inside some programs

        DebugLog "Run Test2 ...  the simply code .. can found in some code"
        Global Time2:Double = jMillisecs()
       
        For Local t2% = 0 To List.Count()-1
        testtype(List.ValueAtIndex(t2)).blablabla2 = 1
        Next
       
        Time2 = jMillisecs() - Time2
        DebugLog "Time2 Time : "+Time2
       
'Test3 ... optimization of test2 variant

        DebugLog "Run Test3 ...  optimization of test2 variant"
        Global Time3:Double = jMillisecs()
       
        Global Arr:Object[] = List.ToArray()
       
        For Local t3% = 0 To Count
                testtype(Arr[t3]).blablabla3 = 1
        Next
       
        Time3 = jMillisecs() - Time3
        DebugLog "Time3 Time : "+Time3

'Test4 ... the very stupid code ...

        DebugLog "Run Test4 ... the hard style coding"
        Global Time4:Double = jMillisecs()

        For Local t4% = 0 To List.Count()
                If t4 < List.Count() Then
                        testtype(List.ValueAtIndex(t4)).blablabla4 = 1
                Else
                        Exit
                End If
        Next

        Time4 = jMillisecs() - Time4
        DebugLog "Test4 Time : "+Time4


DebugLog "End ... thnx"

' EXTRA TIMER CODE

Extern "win32"
        Function QueryPerformanceFrequency(LARGE_INTEGER:Long Var)
        Function QueryPerformanceCounter(LARGE_INTEGER:Long Var)
EndExtern


Type TPerfCounter
        Field Frequency:Double
        Field Freq:Double
        Field basefrequency:Long
        Field Started:Long
        Field LastValue:Long
        Global perfTime:Long        'Global to the type so that a new Local variable doesnt get created
                                'in every function/method. Slight speed increase.
                                                       
        Function GetCounter:Long()                                'Calls QueryPerformanceCounter directly.
                QueryPerformanceCounter(PerfTime)
                Return PerfTime
        End Function
       
        Function Create:TPerfCounter(Freq:Long)                        'Creates a Performance Counter using the Frequency
                Local obj:TPerfCounter=New TPerfCounter
                obj.frequency=Freq
                obj.Freq = Freq
                QueryPerformanceFrequency(obj.baseFrequency)
                obj.Frequency=(obj.basefrequency/obj.Frequency)
                Return OBJ
        End Function

        Method GetTicks:Long()                                        'Get this counter's ticks (uses Frequency)
                QueryPerformanceCounter(PerfTime)
                Return perftime/frequency
        End Method

        Method Start()                                                'Start this counter. (Actually, just set its Started property....)
                QueryPerformanceCounter(PerfTime)
                Started=perfTime
        End Method
       
        Method Stop:Long()                                        'Stop the counter and return the amount of ticks.
                QueryPerformanceCounter(PerfTime)
                LastValue=Long((perftime-Started)/Frequency)
                Return LastValue
        End Method
End Type


Function jMilliSecs:Double()
        Return (Double(Timer.Stop()) / Double(Timer.Freq)) * 1000.0
End Function

у меня выводит вот так
Цитата:

DebugLog:InitOk .. let's run
DebugLog:Run Test1 ... the best optimization
DebugLog:Test1 Time : 1.2745000012218952
DebugLog:Run Test2 ... the simply code .. can found in some code
DebugLog:Time2 Time : 334.37460000067949
DebugLog:Run Test3 ... optimization of test2 variant
DebugLog:Time3 Time : 0.66239999979734421
DebugLog:Run Test4 ... the hard style coding
DebugLog:Test4 Time : 629.71640000119805
DebugLog:End ... thnx
и вот так иногда
Цитата:

DebugLog:InitOk .. let's run
DebugLog:Run Test1 ... the best optimization
DebugLog:Test1 Time : 0.51769999973475933
DebugLog:Run Test2 ... the simply code .. can found in some code
DebugLog:Time2 Time : 338.26229999959469
DebugLog:Run Test3 ... optimization of test2 variant
DebugLog:Time3 Time : 0.64589999988675117
DebugLog:Run Test4 ... the hard style coding
DebugLog:Test4 Time : 597.56499999947846
DebugLog:End ... thnx
Test1 ето работа через EachIn
Test2 простой индексовый цикл с получением обьекта внутри цикла
Test3 ето индексовый цикл но юзает от перевод списка в масив
Test4 показывает тормоз функции Count в LinkedList

исходя из всего самое быстрое ето EachIn
ValueAtIndex ужасно тормозит в linkedlist
Count вообще не кеширует результат .. каждый вызов по новой щитает

в общем смотрите сами, там где можно везде лутче юзать EachIn
функцию ValueAtIndex в циклах лутче избегать использованием масива

сейчас я пока делаю переписывание некоторой игровой логики
но потом буду переделывать связаный список блицмакса
что я хочу сделать :
1)добавить кеширование размера
2)добавить кеширование ValueAtIndex

надо сделать так чтобы при вызове на 2 связи в бок все кешировалось
а то каждый раз перебирать масив слишком дорого
правда все равно тогда будет ужасно тормозить при случайном доступе
такое ощущение что легче дописать отдельно масив там
и получать обьекты из него ... масив пересоздавать при добавлении\удалении обьектов

ps. оптимизируйте свой код ;) :)


Часовой пояс GMT +4, время: 16:19.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot