การสร้างคำบรรยายความยาวในระดับไบต์ที่มีประสิทธิภาพ
ในโลกของการสร้างเครือข่ายคอมพิวเตอร์และการส่งข้อมูล โปรโตคอลเป็นสิ่งจำเป็นสำหรับการอำนวยความสะดวกในการสื่อสารระหว่างอุปกรณ์ หนึ่งในแง่มุมที่สำคัญของโปรโตคอลหลายๆ ตัวคือการจัดการกับความยาวของแพ็กเกจ ซึ่งมักจะแสดงเป็นฟิลด์ในข้อมูลที่ส่ง ความท้าทายเกิดขึ้นเมื่อพัฒนาวิธีการจัดการและเข้ารหัสความยาวในระดับไบต์อย่างมีประสิทธิภาพสำหรับแพ็กเกจที่มีขนาดแตกต่างกัน
ในโพสต์นี้ เราจะลงลึกถึงวิธีการแก้ปัญหาที่มีประสิทธิภาพสำหรับปัญหาเฉพาะ: วิธีการสร้างฟิลด์ความยาวสำหรับแพ็กเกจที่มีความยาวไม่เกิน 32 บิตในระหว่างการทำงาน รองรับขนาดแพ็กเกจที่แตกต่างกันในขณะที่รักษาความสามารถในการอ่านและความสามารถในการดูแลรักษาของรหัส
ความเข้าใจเกี่ยวกับปัญหา
คุณอาจมีโปรโตคอลที่ต้องการฟิลด์ความยาวไม่เกิน 32 บิต และต้องการให้สามารถอธิบายจำนวนไบต์ในแพ็กเกจที่กำหนดได้แบบไดนามิก รหัสต้นฉบับที่ให้ไว้สำหรับงานนี้อาจทำงานได้ แต่มีรายงานว่ามันไม่สวยงามและซับซ้อน ทำให้เข้าถึงได้ยากสำหรับผู้ที่อ่านหรือดูแลรักษามัน
ประเด็นสำคัญ
- ความสามารถในการอ่าน: รหัสที่ซับซ้อนหรือมีความซ้ำซ้อนอาจทำให้ยากสำหรับนักพัฒนาที่จะเข้าใจตรรกะได้อย่างรวดเร็ว
- ประสิทธิภาพ: ในขณะที่รหัสต้นฉบับทำงานได้ยังมีพื้นที่ให้ปรับปรุงทั้งในด้านประสิทธิภาพและความชัดเจน
รหัสต้นฉบับ
นี่คือการสกัดรหัสต้นฉบับที่เรียบง่ายซึ่งสรุปวิธีที่มันประมวลผลความยาวของแพ็กเกจ:
{
extern char byte_stream[];
int bytes = offset_in_packet;
int n = length_of_packet;
int t;
unsigned char first, second, third, fourth;
t = n & 0xFF000000;
first = t >> 24;
if (t) {
byte_stream[bytes++] = first;
write_zeros = 1;
}
// ทำซ้ำสำหรับไบต์ที่สอง, สาม และสี่...
}
รหัสนี้แยกความยาว n
ออกเป็นส่วนประกอบไบต์บุคคลและแนบไปกับสตรีมไบต์ อย่างไรก็ตาม รหัสนี้ใช้ตรรกะซ้ำๆ และตัวแปรกลางที่อาจกระชับได้
วิธีแก้ปัญหา
เพื่อเพิ่มความชัดเจนและประสิทธิภาพของตรรกะนี้ เราจะปรับปรุงรหัสโดยการสร้างฟังก์ชัน การจัดกลุ่มการดำเนินการที่คล้ายกัน และชี้แจงเงื่อนไขที่ไบต์ถูกเขียน ด้านล่างนี้คือการปรับปรุงรหัสในรูปแบบที่เป็นโครงสร้าง
รหัสที่ปรับปรุงแล้ว
นี่คือเวอร์ชันที่ปรับปรุงของรหัส:
/* แนบไบต์ b ไปยังสตรีม เพิ่มดัชนี */
void output(int i, unsigned char b, char stream[], int *index) {
stream[(*index)++] = b;
}
void process_length(char byte_stream[], unsigned int *byte_count, unsigned int length) {
unsigned char first = (length & 0xFF000000) >> 24;
unsigned char second = (length & 0x00FF0000) >> 16;
unsigned char third = (length & 0x0000FF00) >> 8;
unsigned char fourth = (length & 0x000000FF);
if (first)
output(1, first, byte_stream, byte_count);
if (first || second)
output(2, second, byte_stream, byte_count);
if (first || second || third)
output(3, third, byte_stream, byte_count);
output(4, fourth, byte_stream, byte_count); // เสมอเขียนไบต์สุดท้าย
}
การปรับปรุงที่สำคัญ
- การสร้างฟังก์ชัน: โดยการสร้างฟังก์ชัน
output
เรากำจัดความซ้ำซ้อนและปรับปรุงความสามารถในการอ่าน - การจัดกลุ่มตรรกะที่คล้ายกัน: กระบวนการป้องกันและเลื่อนสำหรับแต่ละไบต์จะทำโดยลำดับ ทำให้รูปแบบชัดเจนขึ้น
- การจัดการเงื่อนไข: การตรวจสอบการเขียนไบต์ทำให้ชัดเจนยิ่งขึ้น เพิ่มความเข้าใจในโดยไม่ใช้ตัวแปรที่ไม่จำเป็น
สรุป
ในขณะที่วิธีการก่อนหน้าอาจทำงานได้ แต่การปรับปรุงนี้ให้ความสำคัญกับการเพิ่ม ความสามารถในการอ่าน และ การดูแลรักษา โดยไม่ทำให้ประสิทธิภาพลดลง สำหรับผู้ที่ดูแลหรือใช้โปรโตคอลนี้ การทำความเข้าใจว่าความยาวของแพ็กเกจถูกจัดการอย่างไรจะมีความแตกต่างอย่างมากในระยะยาว
จำไว้ว่าการเขียนโปรแกรมและการออกแบบระบบ ความชัดเจนมักมีความสำคัญเหนือความซับซ้อน โดยเฉพาะอย่างยิ่งในสภาพแวดล้อมที่หลายคนทำงานร่วมกันในโค้ดฐานเดียวกัน ขอให้สนุกกับการเขียนโค้ด!