Slide 1

Slide 1 text

Learn Programming Essence from Ruby patches Mitsutaka Mimura @takkanm

Slide 2

Slide 2 text

Today’s Topic The aim of the session is to review the essence of programming, which you can read from several textbooks for programming, by reading some Ruby code as well as libraries.

Slide 3

Slide 3 text

about me me: name: Mitsutaka Mimura github: takkanm company: EiwaSystemManagement community: Asakusa.rb book: PerfectRuby

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

IUUQCJUMZFTNSVCZLBJHJCFOUP

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

l"KZBSJNPDIJTPVOETMJLF"HJMFEBKBSF@DMVCz .ZCPTTTBJE

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Agenda ✤What is a programming knowledge? ✤Learn from patches. ✤Example case

Slide 12

Slide 12 text

What is Programming Knowladge?

Slide 13

Slide 13 text

What is Knowledge of Programming at Daily Work?

Slide 14

Slide 14 text

Knowledge of Programming Used in Daily Tasks What is required in daily tasks in knowledge on the followings. ✤ Language feature ✤ How to use libraries ✤ How to use freameworks.

Slide 15

Slide 15 text

Knowledge of Programming Seen in Occasions Like University Leactures

Slide 16

Slide 16 text

Knowledge of Programming Seen in Occasions Like University Leactures ✤Algorithm ✤Data Structure ✤Computational Complexity

Slide 17

Slide 17 text

Are they unnecessary at daily work? We usually don't have chances to use such knowledge for writing business codes. But we believe such textbooks still should hold much more secrets, such as an algorithm for writing smarter code or more efficient code.

Slide 18

Slide 18 text

How to study ?

Slide 19

Slide 19 text

Boring Textbooks From textbooks, we can learn much like implementation of algorithms or pros/cons of that. But it is not easy for us to imagine how such knowledges can be applied to our actual writing codes.

Slide 20

Slide 20 text

Book ʮPrograming Techniqueʯ This book is a book that will learn programming techniques read the source of the UNIX command. I was able to get some idea of how they have been utilized in the actual programming is what I learned at school in this book.

Slide 21

Slide 21 text

Proposal -FUTUPUIFNPSFGBNJMJBS UIBUZPVIBWFUPMFBSOUP SFBEUIFQBUDIPG3VCZ

Slide 22

Slide 22 text

Learn from patches

Slide 23

Slide 23 text

Why patch? ✤ Clear code of interest ✤ Information that the many explanation for the patch ✤ Choose the ones likely to read to suit your level

Slide 24

Slide 24 text

What you do learn from a patch? ✤Understanding of libraries and Ruby implementation ✤Understanding of the algorithm ✤Practical implementation

Slide 25

Slide 25 text

At an Asakus.rb Meetup I was taught about Ruby and patches that improve its performance. By reading this, I again about improvements due to change in algorithm.

Slide 26

Slide 26 text

Improving Performance in Ruby I might remind you of advanced and esoteric works like improving GC algorithms or JIT something like that. But some patches are not so hard to read.

Slide 27

Slide 27 text

But, You should be learn about Ruby Interpreter. That said, you need to know the mechanism of Ruby even a little to read the patch of Ruby. So, I will introduce my recommended materials.

Slide 28

Slide 28 text

Ruby Under a Microscope

Slide 29

Slide 29 text

Ruby Under a Microscope

Slide 30

Slide 30 text

doc/extention.rdoc (in ruby source tree)

Slide 31

Slide 31 text

yotii23’s slide : WALK AROUND THE Ruby FOREST MORE DEEPLY.

Slide 32

Slide 32 text

Example case

Slide 33

Slide 33 text

https://bugs.ruby-lang.org/issues/12142

Slide 34

Slide 34 text

about st_table Ruby's core holds a 'st_table' structure that have been used in many codes. The contents of 'Hash' in Ruby are also contained within the strcture.

Slide 35

Slide 35 text

review of Hash structure

Slide 36

Slide 36 text

review of Hash hash = Hash.new hash[:key_a] = 1

Slide 37

Slide 37 text

review of Hash )BTI5BCMF

Slide 38

Slide 38 text

review of Hash ,&: 7"-6& LFZ@B )BTI5BCMF

Slide 39

Slide 39 text

review of Hash ,&: 7"-6& LFZ@B )BTI GVODUJPO )BTI5BCMF

Slide 40

Slide 40 text

review for Hash ,&: 7"-6& LFZ@B )BTI GVODUJPO )BTI5BCMF

Slide 41

Slide 41 text

review for Hash ,&: 7"-6& LFZ@B )BTI5BCMF

Slide 42

Slide 42 text

in Ruby ,&: 7"-6& LFZ@B

Slide 43

Slide 43 text

in Ruby ,&: 7"-6& LFZ@B TU@UBCMF TU@UBCMF@FOUSZ

Slide 44

Slide 44 text

st_table struct st_table { const struct st_hash_type *type; st_index_t num_bins; unsigned int entries_packed : 1; st_index_t num_entries : ST_INDEX_BITS - 1; union { struct { struct st_table_entry **bins; void *private_list_head[2]; } big; struct { struct st_packed_entry *entries; st_index_t real_entries; } packed; } as; };

Slide 45

Slide 45 text

st_table_entry struct st_table_entry { st_index_t hash; st_data_t key; st_data_t record; st_table_entry *next; struct list_node olist; };

Slide 46

Slide 46 text

Within Ruby ,&: 7"-6& LFZ@B TU@UBCMF TU@UBCMF@FOUSZ

Slide 47

Slide 47 text

Within Ruby LFZ SFDPSE LFZ@B TU@UBCMFCJOT TU@UBCMF@FOUSZ

Slide 48

Slide 48 text

Further add a key LFZ SFDPSE LFZ@B LFZ SFDPSE LFZ@C )BTI GVODUJPO

Slide 49

Slide 49 text

Within Ruby LFZ SFDPSE LFZ@B LFZ SFDPSE LFZ@C

Slide 50

Slide 50 text

If Hash values conflict LFZ SFDPSE LFZ@B LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D )BTI GVODUJPO

Slide 51

Slide 51 text

Algorithms to detour Hash conflict

Slide 52

Slide 52 text

Separate chaining In case the evaluated values of a hash function are identical, a single address in a hash table is allowed to hold multiple elements.

Slide 53

Slide 53 text

Separate chaining LFZ SFDPSE LFZ@B LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D )BTI GVODUJPO

Slide 54

Slide 54 text

Separate chaining LFZ SFDPSE LFZ@B LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D

Slide 55

Slide 55 text

Current Ruby Ruby use Separate chaining. Too see its implementation, you can refer to the function that inserts into hashes.

Slide 56

Slide 56 text

st_insert int st_insert(register st_table *table, register st_data_t key, st_data_t value) { st_index_t hash_val; register st_index_t bin_pos; register st_table_entry *ptr; hash_val = do_hash(key, table); if (table->entries_packed) { st_index_t i = find_packed_index(table, hash_val, key); if (i < table->real_entries) { PVAL_SET(table, i, value); return 1; } add_packed_direct(table, key, value, hash_val); return 0; }

Slide 57

Slide 57 text

st_insert FIND_ENTRY(table, ptr, hash_val, bin_pos); if (ptr == 0) { add_direct(table, key, value, hash_val, bin_pos); return 0; } else { ptr->record = value; return 1; } }

Slide 58

Slide 58 text

add_direct static inline void add_direct(st_table *table, st_data_t key, st_data_t value, st_index_t hash_val, register st_index_t bin_pos) { register st_table_entry *entry; if (table->num_entries > ST_DEFAULT_MAX_DENSITY * table->num_bins) { rehash(table); bin_pos = hash_pos(hash_val, table->num_bins); } entry = new_entry(table, key, value, hash_val, bin_pos); list_add_tail(st_head(table), &entry->olist); table->num_entries++; }

Slide 59

Slide 59 text

new_entry static inline st_table_entry * new_entry(st_table * table, st_data_t key, st_data_t value, st_index_t hash_val, register st_index_t bin_pos) { register st_table_entry *entry = st_alloc_entry(); entry->next = table->bins[bin_pos]; table->bins[bin_pos] = entry; entry->hash = hash_val; entry->key = key; entry->record = value; return entry; }

Slide 60

Slide 60 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D )BTI GVODUJPO

Slide 61

Slide 61 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D

Slide 62

Slide 62 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D

Slide 63

Slide 63 text

Feature #12142 Hash tables with open addressing switching to open addressing hash tables for access by keys. Removing hash collision lists lets us avoid *pointer chasing*, a common problem that produces bad data locality. I see a tendency to move from chaining hash tables to open addressing hash tables due to their better fit to modern CPU memory organizations.

Slide 64

Slide 64 text

Open addressing A way to insert all Hash elements in a Hash table. When the evaluation results of Hash function conflict, the element is placed in another empty space.

Slide 65

Slide 65 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D )BTI GVODUJPO

Slide 66

Slide 66 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D )BTI GVODUJPO JOD

Slide 67

Slide 67 text

If conflict Hash value LFZ SFDPSE LFZ@C LFZ ̍ SFDPSE LFZ@D

Slide 68

Slide 68 text

Read patch

Slide 69

Slide 69 text

Corresponding Patches Half an year has passed since the original proposal, and various refinements have been adopted since. This talk will be based on the latest attached st_table_with_array2 branch of funny-falcon/ruby.

Slide 70

Slide 70 text

st_table struct st_table { const struct st_hash_type *type; union { struct st_table_entry* entries; st_idx_t* bins; uint8_t* smallbins; uint16_t* medbins; } as; st_idx_t num_entries; st_idx_t first, last; unsigned sz : 8; unsigned rebuild_num : 24; };

Slide 71

Slide 71 text

st_table_entry struct st_table_entry { st_idx_t hash; st_idx_t next; st_data_t key; st_data_t record; };

Slide 72

Slide 72 text

new st_table TU@UBCMF CJOT FOUSJFT

Slide 73

Slide 73 text

st_insert int st_insert(register st_table *table, register st_data_t key, st_data_t value) { st_idx_t hash_val, idx; hash_val = do_hash(key, table); idx = find_entry(table, key, hash_val); if (idx == IDX_NULL) { add_direct(table, key, value, hash_val); return 0; } else { table->as.entries[idx].record = value; return 1; } }

Slide 74

Slide 74 text

find_entry static inline st_idx_t find_entry(const st_table *table, st_data_t key, st_idx_t hash_val) { unsigned rebuild_num ST_UNUSED = table->rebuild_num; if (st_sz[table->sz].nbins == 0) { st_idx_t idx = table->first, last = table->last; st_table_entry* ptr = &table->as.entries[idx]; for (; idx < last; idx++, ptr++) { if (ptr->hash == hash_val && EQUAL(table, key, ptr)) { return idx; } } st_assert(rebuild_num == table->rebuild_num); return IDX_NULL;

Slide 75

Slide 75 text

find_entry } else { st_idx_t bin_pos = hash_pos(hash_val, table->sz); st_idx_t idx = bin_get(table, bin_pos); FOUND_ENTRY; while (PTR_NOT_EQUAL(table, idx, hash_val, key)) { COLLISION; idx = table->as.entries[idx].next; } st_assert(rebuild_num == table->rebuild_num); return idx; } }

Slide 76

Slide 76 text

add_direct static inline void add_direct(st_table *table, st_data_t key, st_data_t value, st_idx_t hash_val) { register st_table_entry *entry; st_idx_t en_idx, bin_pos; if (table->last == st_sz[table->sz].nentries) { st_rehash(table); }

Slide 77

Slide 77 text

add_direct en_idx = table->last; table->last++; entry = &table->as.entries[en_idx]; if (st_sz[table->sz].nbins != 0) { bin_pos = hash_pos(hash_val, table->sz); entry->next = bin_get(table, bin_pos); bin_set(table, bin_pos, en_idx); } entry->hash = hash_val; entry->key = key; entry->record = value; table->num_entries++; }

Slide 78

Slide 78 text

new st_table TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@B

Slide 79

Slide 79 text

TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@B new st_table LFZ@B

Slide 80

Slide 80 text

̌ TU@UBCMF CJOT FOUSJFT LFZ@B LFZ WBMVF IBTI LFZ@B new st_table

Slide 81

Slide 81 text

̌ TU@UBCMF CJOT FOUSJFT LFZ@B LFZ WBMVF IBTI LFZ@C new st_table

Slide 82

Slide 82 text

̌ TU@UBCMF CJOT FOUSJFT LFZ@B LFZ@C LFZ WBMVF IBTI LFZ@C new st_table

Slide 83

Slide 83 text

̌ ̍ TU@UBCMF CJOT FOUSJFT LFZ@B LFZ@C LFZ WBMVF IBTI LFZ@C new st_table

Slide 84

Slide 84 text

̌ ̍ TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@D new st_table LFZ@B LFZ@C

Slide 85

Slide 85 text

̌ ̍ TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@D LFZ@D new st_table LFZ@B LFZ@C

Slide 86

Slide 86 text

̌ ̍ TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@D ̍ new st_table LFZ@D LFZ@B LFZ@C

Slide 87

Slide 87 text

̌ ̎ TU@UBCMF CJOT FOUSJFT LFZ WBMVF IBTI LFZ@D new st_table ̍ LFZ@D LFZ@B LFZ@C

Slide 88

Slide 88 text

Feeling after read patch ✤ By reading the patch of the description, it is easy to guess the contents, it became help Read. ✤ Patch format was easy to follow the changes. ✤ Than what you have learned in the book, knowing the practical implementation.

Slide 89

Slide 89 text

Conclusion

Slide 90

Slide 90 text

Conclusion By reading real code, We suppose you will be able to tell the scenarios where ideas described in books are used. By reading patches, I think you can easily tell the main changes you are interested in. I recommend you to try code-reading to rediscover the knowledge of programming you learned. How about that?