veer66

rustlang

I try different to serialize my data before saving into RocksDB. #rustlang

serde_json

Time

real    4m11.713s
user    13m32.809s
sys     1m33.887s

Space

2.1GB

bincode

Time

real    2m13.772s
user    10m45.541s
sys     1m41.670s

Space

1.1GB

serde-lexpr (S-Expression)

Time

real    10m54.622s
user    22m11.570s
sys     1m10.663s

Space

2.2GB

serde_cbor

Time

real    2m52.010s
user    12m17.019s
sys     1m32.687s

Space

1.7GB

CBOR and bincode are obviously faster than JSON and S-Expression. CBOR is a less efficient than bincode. However, more programming languages support CBOR.

Given I have a file of document id and text unit id. For example:

doc-id, text-unit-ids
1,100,200,300
2,50,8,1,6

I want to keep them in a list of doc-id, text-unit-id pairs. For example:

1,100
1,200
1,300
2,50
2,8
2,1
2,6

So I defined my variable in Rust, as follow:

let word_id_tu_ids: Vec<(u32, u32)> = vec![];

Sometimes I have a problem that I flipped them. I put a pair of text-unit-id and doc-id instead of text-unit-it and doc-id. For example, I put 100,1 instead of 100,1.

By (u32, u32), the Rust compiler cannot help me. So I tried:

type WordId = u32;
type DocId = u32;

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

It didn't help. So I tried struct instead.

struct WordId(u32);
struct DocId(u32);

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

Now the compiler can detect the error. However, maybe it is not clear to human eyes. So I defined another struct.

struct WordId(u32);
struct DocId(u32);

struct WordIdDocId {
    word_id: WordId,
    doc_id: DocId,
}

fn push(w: WordId, d: DocId) {
    let mut v: Vec<WordIdDocId> = vec![];
    v.push(WordIdDocId {word_id: w, doc_id: d});
}

Now it is clear to human eyes and the compiler. Anyways, is it what people call over-engineering? What if I want to:

let u = w + 1;

We can do it in Rust, but the code is going to be even longer. published: true description: tags: #rust #rustlang //coverimage: https://directurltoimage.jpg


Given I have a file of document id and text unit id. For example:

doc-id, text-unit-ids
1,100,200,300
2,50,8,1,6

I want to keep them in a list of doc-id, text-unit-id pairs. For example:

1,100
1,200
1,300
2,50
2,8
2,1
2,6

So I defined my variable in Rust, as follow:

let word_id_tu_ids: Vec<(u32, u32)> = vec![];

Sometimes I have a problem that I flipped them. I put a pair of text-unit-id and doc-id instead of text-unit-it and doc-id. For example, I put 100,1 instead of 100,1.

By (u32, u32), the Rust compiler cannot help me. So I tried:

type WordId = u32;
type DocId = u32;

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

It didn't help. So I tried struct instead.

struct WordId(u32);
struct DocId(u32);

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

Now the compiler can detect the error. However, maybe it is not clear to human eyes. So I defined another struct.

struct WordId(u32);
struct DocId(u32);

struct WordIdDocId {
    word_id: WordId,
    doc_id: DocId,
}

fn push(w: WordId, d: DocId) {
    let mut v: Vec<WordIdDocId> = vec![];
    v.push(WordIdDocId {word_id: w, doc_id: d});
}

Now it is clear to human eyes and the compiler. Anyways, is it what people call over-engineering? What if I want to:

let u = w + 1;

We can do it in Rust, but the code is going to be even longer.

เขียน #rustlang แบบ

(word_id, textunit_id) 

วันเดียวพอจำได้หรอก เขียนไปนาน ๆ อาจจะพลาดใส่

(textunit_id, word_id)

ก็ได้

อันนี้ static type อาจจะวืดเพราะทั้ง textunit-id และ word-id ก็เป็น u32 ทั้งคู่ อาจจะแก้แบบนี้สร้าง type มาใหม่เลย WordId กับ TextunitId แต่มันก็เหนื่อยอยู่นะ

ไม่ก็ใช้ struct แทน เช่น

struct WordIdTextunitId {
    word_id: u32,
    textunit_id: u32,
}

อันนี้เขียนง่ายดี แต่ compiler ไม่ได้ช่วยอะไรมากนะ ก็คือ programmer ก็ดูเอาเมื่อไหร่เขียน

WordIdTextunitId { word_id: textunit_id, textunit_id: word_id }

แบบนี้ก็ผิด โปรแกรมเมอร์เห็นเอง แต่ใส่สลับกัน compiler มันก็ผ่านนะ

แล้วคิดไปติดมามันก็พอกับเขียน Clojure เลย

{:word-id word-id
 :textunit-id textunit-id}

แบบนี้ก็ชัดเจนอยู่แล้ว ไม่ต้องประกาศ struct ด้วย หรือจะใช้ defstruct เลยก็ได้

ใน Common Lisp ก็คล้าย ๆ กัน def struct ก็ได้ จะทำเป็น alist ก็ได้

(list (cons :word-id word-id) 
       (cons :textunit-id textunit-id))

แบบนี้ก็ได้

กลับมา Rust จะจัดหนักแบบ ทำแบบนี้ก็บึ้มอยู่ดี

type WordId = u32;
type TextunitId = u32;

struct WordIdTextUnitId {
    word_id: WordId,
    textunit_id: TextunitId,
}

fn main() {
   let w: WordId = 1;
   let t: TextunitId = 2;
   let x = WordIdTextUnitId { word_id: t, textunit_id: w};
}

สลับได้ compiler ไม่ช่วยอะไร

แต่ถ้าทำเป็น struct หมดเลย

struct WordId(u32);
struct TextunitId(u32);

struct WordIdTextUnitId {
    word_id: WordId,
    textunit_id: TextunitId,
}

fn main() {
    let w = WordId(1);
    let t = TextunitId(2);
    let x = WordIdTextUnitId { word_id: t, textunit_id: w};
}

แบบนี้ compiler มันจะช่วยได้รู้แล้วว่าสลับกัน

แต่ก็จะมาเจอว่าผมอยากได้

let v = w + 1; 

แบบนี้ทำไง ก็มีวิธีทำหลายทางนะ เพียงแต่มันก็ต้องออกแรง