Rust - 纯Safe双向链表

该代码仅仅提供学习与交流,你要是和我考究性能,你开心就好。

Rust实现

struct Node<T> {
    data: Box<T>,
    head: Option<Arc<Mutex<Node<T>>>>,
    next: Option<Arc<Mutex<Node<T>>>>,
}

impl <T> Node<T> {
    fn new(data: T) -> Self {
        Node {
            data: Box::new(data),
            head: None,
            next: None,
        }
    }
}

struct BiLinkedList<T> {
    head: Option<Arc<Mutex<Node<T>>>>,
    tail: Option<Arc<Mutex<Node<T>>>>,
}

impl <T> BiLinkedList<T> {
    fn new() -> Self {
        BiLinkedList {
            head: None,
            tail: None,
        }
    }

    fn push(&mut self, data: T) {
        let mut node = Node::new(data);
        if self.head.is_none() {
            let head = Arc::new(Mutex::new(node));
            self.tail = Some(Arc::clone(&head));
            self.head = Some(head);
        } else {
            let mut head = self.head.take().unwrap();
            node.next = Some(head.clone());
            let new_head = Arc::new(Mutex::new(node));
            let mut head = head.lock().unwrap();
            head.head = Some(Arc::clone(&new_head));
            self.head = Some(new_head);
        }
    }

    fn pop(&mut self) -> Option<Arc<Mutex<Node<T>>>> {
        if self.head.is_none() {
            return None;
        }
        let head = self.head.take().unwrap();
        let lock = head.lock().unwrap();
        if lock.next.is_some() {
            self.head = lock.next.clone();
        } else {
            self.head = None;
            self.tail = None;
        }
        drop(lock);
        Some(head)
    }
}

#[tokio::main]
async fn main() {
    let start_time = Instant::now();


    let mut sum = 0;
    for _ in 0..100_0000 {
        let mut list = BiLinkedList::<i32> {
            head: None,
            tail: None,
        };
        list.push(1);
        list.push(2);
        list.push(3);
        list.push(4);
        list.push(5);
        list.push(6);
        list.push(7);
        list.push(8);
        let mut node = list.head.clone();
        while node.is_some() {
            let mutex = node.clone().unwrap();
            let mut lock = mutex.lock().unwrap();
            sum += *lock.data.as_ref();
            node = lock.next.clone();
        }
    }
    println!("{}", sum);
    println!("Cost: {}ms", start_time.elapsed().as_millis());
}

C++代码

template<class T>
class Node {
public:
    T* data;
    Node<T>* prev;
    Node<T>* next;

    Node(T* data) {
        this->data = data;
        this->prev = nullptr;
        this->next = nullptr;
    }
};

template<class T>
class BiLinkedList {
public:
    Node<T>* head = nullptr;
    Node<T>* tail = nullptr;

    void append(T* data) {
        Node<T>* newNode = new Node<T>(data);
        if (tail) {
            tail->next = newNode;
            newNode->prev = tail;
            tail = newNode;
        } else {
            head = tail = newNode;
        }
    }

    void prepend(T* data) {
        Node<T>* newNode = new Node<T>(data);
        if (head) {
            head->prev = newNode;
            newNode->next = head;
            head = newNode;
        } else {
            head = tail = newNode;
        }
    }

    void remove(Node<T>* node) {
        if (!node) return;

        if (node->prev) {
            node->prev->next = node->next;
        } else {
            head = node->next;
        }

        if (node->next) {
            node->next->prev = node->prev;
        } else {
            tail = node->prev;
        }

        delete node->data;
        delete node;
    }

    Node<T>* find(T* data) {
        Node<T>* current = head;
        while (current) {
            if (*(current->data) == *data) {
                return current;
            }
            current = current->next;
        }
        return nullptr;
    }

    int printList() {
        int sum = 0;
        Node<T>* current = head;
        while (current) {
            //std::cout << *(current->data) << " ";
            sum += *(current->data);
            current = current->next;
        }
        return sum;
    }

    ~BiLinkedList() {
        Node<T>* current = head;
        while (current) {
            Node<T>* next = current->next;
            //delete current->data; 测试用例,数据在栈,无需delete
            delete current;
            current = next;
        }
    }
};

int main() {
    auto start = std::chrono::high_resolution_clock::now();
    int sum = 0;
    for (int i = 0; i < 1000000; ++i) {
        BiLinkedList<int> list{};
        int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8;
        list.prepend(&a);
        list.prepend(&b);
        list.prepend(&c);
        list.prepend(&d);
        list.prepend(&e);
        list.prepend(&f);
        list.prepend(&g);
        list.prepend(&h);
        sum += list.printList();
    }
    std::cout << sum << "\n";
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Cost: "<< duration << "ms" << std::endl;
    return 0;
}

表现

// Rust
36000000
Cost: 1735ms
// C++
36000000
Cost: 252ms