Go Back   RunUO - Ultima Online Emulation > Developer's Corner > Programming > C#

C# C# Discussion

Reply
 
Thread Tools Display Modes
Old 08-28-2006, 09:31 PM   #1 (permalink)
Forum Newbie
 
Join Date: Apr 2006
Location: Kenilworth, England
Age: 22
Posts: 1
Send a message via MSN to Apolluon
Default Listener Queue

I've been wanting to write a quick asnychronous server in C# just to see how -architecture wise- servers piece together. So I've been looking in to the core code release of RunUO. I've noticed that the Listener class implements a Queue from System.Collections.Generic -named m_Accepted. Inside the Listener class the queue is added to when a connection is being handled.

I was wondering why the queue is implemented? (Why implement a queue if it's function is to monitor the current connections? Why not a list?)

Last edited by Apolluon; 08-28-2006 at 09:33 PM.
Apolluon is offline   Reply With Quote
Old 08-28-2006, 10:08 PM   #2 (permalink)
Forum Expert
 
TheOutkastDev's Avatar
 
Join Date: Sep 2002
Location: Houston, Texas
Age: 22
Posts: 3,933
Default

Queue's aoperate as in a first in, first out fashion. Since processing new connections is best handled in the order they are received, using a list is pointless since the queue collection that gives us the exact functionality we need.
TheOutkastDev is offline   Reply With Quote
Old 08-28-2006, 11:21 PM   #3 (permalink)
Forum Expert
 
Courageous's Avatar
 
Join Date: Nov 2005
Location: San Diego, CA
Posts: 1,824
Default

Linked lists can be made to do that too: push tail, pop head. Queues have the added advantage of "relative priority," and are often implemented using a priority heap structure. I doubt there would be much difference here one way or the other. Strictly theoretically, a linked list might have better behavior for use as a simple fifo. Problem is, the experiment's not even really worth it. CPU and IO time is all dominately elsewhere in RunUO. *Shrug*.

C//
Courageous is offline   Reply With Quote
Old 08-29-2006, 04:21 AM   #4 (permalink)
Forum Expert
 
Join Date: Jul 2005
Location: Istanbul/Turkey
Age: 27
Posts: 425
Default

well actually although at first it seems that it might not be big deal to use either of them, using an arraylist might not be really good idea because of the implementation.

Removing a object from an arraylist has lots of overhead: it copies the complete inner array. However this behaviour doesnt exist in Queue and it is a really fast implementation.

You might use a workaround for this problem. Yo dont remove an object just after it is processed. You could process some amount of packet then remove them all. However, queue implementation still looks more efficient than this.

Code:
//ArrayList
public virtual void RemoveAt(int index)
{
      if ((index < 0) || (index >= this._size))
      {
            throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
      }
      this._size--;
      if (index < this._size)
      {
            Array.Copy(this._items, index + 1, this._items, index, this._size - index);
      }
      this._items[this._size] = null;
      this._version++;
}

public virtual void RemoveRange(int index, int count)
{
      if ((index < 0) || (count < 0))
      {
            throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
      }
      if ((this._size - index) < count)
      {
            throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
      }
      if (count > 0)
      {
            int num1 = this._size;
            this._size -= count;
            if (index < this._size)
            {
                  Array.Copy(this._items, index + count, this._items, index, this._size - index);
            }
            while (num1 > this._size)
            {
                  this._items[--num1] = null;
            }
            this._version++;
      }
}

//Queue
public virtual object Dequeue()
{
      if (this._size == 0)
      {
            throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue"));
      }
      object obj1 = this._array[this._head];
      this._array[this._head] = null;
      this._head = (this._head + 1) % this._array.Length;
      this._size--;
      this._version++;
      return obj1;
}
__________________
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

Last edited by noobie; 08-29-2006 at 09:59 AM.
noobie is offline   Reply With Quote
Old 08-29-2006, 01:16 PM   #5 (permalink)
Forum Expert
 
Courageous's Avatar
 
Join Date: Nov 2005
Location: San Diego, CA
Posts: 1,824
Default

Quote:
Removing a object from an arraylist has lots of overhead...
Agree. One could implement a linked list fairly trivially, though.

It wouldn't hurt to try such an experiment, if someone were so inclined: I just wouldn't expect much... perhaps nothing noticeable at all (I've seen binary heaps that perform better than linked lists, due to cache locality alone in some instances, regardless of the theoreticals... O(1) for the linked list and O(log N) for the heap).

If one is going to get into CS-like performance experiments with the core, better to profile it, or better yet ask the devs where their problem areas are in execution speed. I.e., if one were to deliver a set of performance miracles to the dev team, where would they like those miracles to be?

C//
Courageous is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5