xxdem Posted July 19, 2016 Posted July 19, 2016 (edited) ConcurrentDictionary is similar to ConcurrentHashMap ? Cause atm you simply need a HashMap, as you simply use it to check, and that map is fed normally only once (and content never replaced, removed or edited anew). You obviously didn't noticed that he creates and runs a new thread for handling and running a dumb client request (they may come as thousands per second on a decent server), so I guess optimization and efficieny is the least of his concerns for now at least, his just making things that should work no matter the cost. Edited July 19, 2016 by xxdem Quote
Elfo Posted July 19, 2016 Author Posted July 19, 2016 Threadhandling and concurrency and async tasks is handled differently in CLR than JVM so you cant compare it. My thread will be disposed in milliseconds once its executed. If the call was synchronous i would have performance issues. All of those thread will be handled by enqueue eventually if they need to. Quote
Tryskell Posted July 19, 2016 Posted July 19, 2016 (edited) You obviously didn't noticed that he creates and runs a new thread for handling and running a dumb client request (they may come as thousands per second on a decent server), so I guess optimization and efficieny is the least of his concerns for now at least, his just making things that should work no matter the cost. Until I missed the point, the map is used as a static checker for packet opcode and class reference, nothing else. It worked fine before. I don't see the use of replacement, except winning 200 lines (at best and only for GS) on a never edited class. ---- K then, if it's differently handled. I clearly doubt concurrent is better performance than a simple switch = new object though. It must perform similar anyway. Edited July 19, 2016 by Tryskell Quote
Elfo Posted July 19, 2016 Author Posted July 19, 2016 Until I missed the point, the map is used as a static checker for packet opcode and class reference, nothing else. It worked fine before. I don't see the use of replacement, except winning 200 lines (at best and only for GS) on a never edited class. ---- K then, if it's differently handled. I clearly doubt concurrent is better performance than a simple switch = new object though. It must perform similar anyway. Only time will tell. Forget the concurrent keyword. It is just there because i use a Synchronization attribute in the class . Technically it could be a simple Dictionary and i will test it that way too as a simple dictionary upon population is almost 2 times faster. Quote
Elfo Posted July 20, 2016 Author Posted July 20, 2016 You obviously didn't noticed that he creates and runs a new thread for handling and running a dumb client request (they may come as thousands per second on a decent server), so I guess optimization and efficieny is the least of his concerns for now at least, his just making things that should work no matter the cost. Interestingly enough I debugged the threads and yeah they where disposed really fast but I removed them, see how it performs and add a queue if it is needed. About the benchmarking it performs exactly the same (Apart of the initial Dictionary loading which happens on startup anyway) but it is just way more easy to maintain and debug (which is very important for a project that is still adding the packets). I can add a packet in one line instead of 5 and stepping through the code it way better. Quote
xxdem Posted July 20, 2016 Posted July 20, 2016 Interestingly enough I debugged the threads and yeah they where disposed really fast but I removed them, see how it performs and add a queue if it is needed. About the benchmarking it performs exactly the same (Apart of the initial Dictionary loading which happens on startup anyway) but it is just way more easy to maintain and debug (which is very important for a project that is still adding the packets). I can add a packet in one line instead of 5 and stepping through the code it way better. Just make 2-8 Thread workers and add Client Requests on their Queues, these threads are supposed to sleep a given time and execute from the queue forever. I can tell you many reasons why creating a new thread sucks for every client request one of them and most important from me is that the Player has direct access on your resources both soft and hard, whereas in a worker queue design he can't Quote
Elfo Posted July 20, 2016 Author Posted July 20, 2016 Just make 2-8 Thread workers and add Client Requests on their Queues, these threads are supposed to sleep a given time and execute from the queue forever. I can tell you many reasons why creating a new thread sucks for every client request one of them and most important from me is that the Player has direct access on your resources both soft and hard, whereas in a worker queue design he can't Yeah Enqueue should be fine. Really glad i got rid of that ugly switch statement. Thanks for the recommendation. Quote
xxdem Posted July 20, 2016 Posted July 20, 2016 Yeah Enqueue should be fine. Really glad i got rid of that ugly switch statement. Thanks for the recommendation. the switch statement has nothing to do with that, it was ugly but supper fast. Your design has the overhead of searching every time for the class and then initiating its instance through reflection. I guess its 100x slower but for sure cleaner and the overhead impact is unnoticeable Quote
Elfo Posted July 20, 2016 Author Posted July 20, 2016 the switch statement has nothing to do with that, it was ugly but supper fast. Your design has the overhead of searching every time for the class and then initiating its instance through reflection. I guess its 100x slower but for sure cleaner and the overhead impact is unnoticeable It is as fast as checking a small HashMap for a key value which is technically the same as as switch of the same size. Quote
xxdem Posted July 20, 2016 Posted July 20, 2016 It is as fast as checking a small HashMap for a key value which is technically the same as as switch of the same size. Im not talking about the HashMap, HashMap is super fast O(1) in most cases, Im talking about Class.newInstance which most probably is done with reflection on the runtime, I doubt that EnterWorld.class.getConstructor().newInstance() is anything close to "new EnterWorld()" in terms of perfomance Quote
Elfo Posted July 20, 2016 Author Posted July 20, 2016 Im not talking about the HashMap, HashMap is super fast O(1) in most cases, Im talking about Class.newInstance which most probably is done with reflection on the runtime, I doubt that EnterWorld.class.getConstructor().newInstance() is anything close to "new EnterWorld()" in terms of perfomance It is indeed using reflection but it caches the action so once it's done then it acts the same as new EnterWorld(), because it uses System instead of Reflection to create the instances. But that means that every single packet would have to be created with reflection at least once. Quote
Elfo Posted July 21, 2016 Author Posted July 21, 2016 After some benchmarking it seems that in heavy load (50kk iterations) Activator.CreateInstance is up to 4 times slower (can get higher). I know that's nothing for l2 but i wanna get as much horsepower as possible so i will be replacing Activator with compiled lambda expressions. Quote
Elfo Posted July 31, 2016 Author Posted July 31, 2016 Added the basic implementation of a Plugin API. Simply create a class library on .NET Framework 4.6, extend the Plugin class and override whichever method you want. Then drop the dll in the plugins folder and thats it. Quote
pirama Posted August 3, 2016 Posted August 3, 2016 (edited) realy ( nice job ) but ... this session is for l2j project and this project ( as you said is C# ) why you create topic on l2j ? read before posting Edited August 3, 2016 by pirama Quote
Elfo Posted August 3, 2016 Author Posted August 3, 2016 (edited) a Edited October 1, 2021 by Elfocrash Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.