Thursday, June 5, 2014

[TUT] Packed vs Unpacked Strings


Packed vs Unpacked Strings

Đề nghị trước khi đọc các tài liệu nếu bạn không hiểu làm thế nào con số này được lưu trữ trong bộ nhớ: http://en.wikipedia.org/wiki/Binary_numeral_system

The unpacked string

Một chuỗi giải nén là loại chuỗi mà bạn thường (có thể luôn luôn) thấy được sử dụng trong AMX-X plugins. Nó là một mảng của các ô nhớ  4-byte, mỗi ô đại diện cho một ký tự cá nhân trong chuỗi. Mỗi ký tự trong một chuỗi (cả đóng gói và giải nén) được đại diện bởi một số nguyên của 0-255. Để đại diện cho một số nguyên của 0-255, chỉ có 1 byte là cần thiết, tuy nhiên, chuỗi giải nén phân bổ 4-byte cho mỗi nhân vật để lại 3-byte bộ nhớ sử dụng cho mỗi ô nhớ. Dưới đây minh họa điều này:

Code:
Một byte gồm 8-bit, dưới đây là một ô của 4-byte hoặc 32-bit.
Đây là cách một ký tự được lưu trữ trong một ô chuỗi giải nén.
Chỉ bit 1-8 được sử dụng bởi vì đó là tất cả những gì cần thiết để lưu trữ các giá trị 0-255.

0000 0000 0000 0000 0000 0000 0000 0000 = 0
0000 0000 0000 0000 0000 0000 1111 1111 = 255

Các bit màu đỏ là chưa sử dụng \ bộ nhớ bị lãng phí. Lãng phí là 3 byte cho mỗi ô nhớ (24-bit)
The packed string

Một chuỗi đóng gói cũng là một mảng của các ô nhớ  4-byte nhưng cách bố trí bộ nhớ được "đóng gói" để tất cả bộ nhớ trong tế bào được sử dụng để lưu trữ dữ liệu. Điều này dẫn đến yêu cầu bộ nhớ cho mỗi ký tự là 1 byte (8-bit) trái ngược với 4 byte (32-bit) trong một chuỗi giải nén. Khi bạn khai báo một chuỗi đóng gói bạn vẫn còn khai báo một mảng của các ô nhớ  4-byte nhưng mỗi ô nhớ sẽ tổ chức 4 ký tự thay vì chỉ một như nó sẽ ở một chuỗi giải nén. Lưu ý: Một chuỗi đóng gói chỉ có thể giữ các ký tự từ một bộ ký tự single-byte, chẳng hạn như ascii hoặc một trong các bộ ascii mở rộng

Code:
Đây là một tế bào 4-byte sẽ xuất hiện trong hình thức đóng gói. Mỗi màu sắc đại diện cho
lưu trữ của một ký tự riêng trong chuỗi. Thông báo, không có gì là lãng phí.

Đây là phiên bản đóng gói của từ "pack"

0111 0000 0110 0001 0110 0011 0110 1011
Khi nào tôi nên sử dụng một chuỗi đóng gói trên một chuỗi giải nén?

Packed

  • Lưu trữ bất kỳ giá trị số trong khoảng 0 - 255
  • Lưu trữ văn bản ascii

Unpacked

  • Lưu trữ các giá trị số> 255
  • Lưu trữ văn bản unicode hoặc chuẩn bất kỳ khác ASCII

Làm thế nào để xác định và vận dụng một chuỗi đóng gói trong AMX-X?

Việc sử dụng gần giống như một chuỗi giải nén bình thường ngoại trừ truy cập vào chuỗi. Bạn không thể in \ thao tác toàn bộ chuỗi đóng gói như bạn có thể giải nén một. Trước tiên bạn phải giải nén nó và sau đó in / định dạng / etc. 


Dưới đây là hai chức năng nhỏ để đóng gói và giải nén một chuỗi. Tôi không biết làm thế nào 'đắt' sử dụng chức năng này giải nén trên dây lớn sẽ được nhưng đó là lựa chọn duy nhất cho bây giờ. Nếu có ai phát hiện ra một cách để làm điều này mà không có một chức năng bổ sung xin vui lòng PM tôi.
PHP Code:
public strpack( const szUnpacked[] , szPacked[] )
{   
    new 
i;
    while((
szPacked{i} = szUnpacked[i++])){}
}

public 
strunpack( const szPacked[] , szUnpacked[] )
{   
    new 
i;
    while((
szUnpacked[i] = szPacked{i++})){}
}  
Để xác định một chuỗi bạn định nghĩa nó như bình thường với kích thước mong muốn và thêm 'char' nhận dạng sau khi nó. Bạn sử dụng cùng một quy tắc thêm 1 với kích thước thực tế cần thiết để nhường chỗ cho các ký tự chấm dứt null. Bạn cũng phải bao gồm các '!' nhân vật trước khi bắt đầu "khi giao chuỗi vào biến.
PHP Code:
new szString[11 char] = !"The string";  
Để tham khảo một tế bào riêng lẻ trong chuỗi, nó cũng giống như với một loạt giải nén nhưng thay vì sử dụng [] bạn sử dụng {}.
PHP Code:
Unpacked szString[5];Packed szString{5};  
Nhưng chính xác bao nhiêu bộ nhớ không sử dụng một chuỗi đóng gói tiết kiệm cho tôi?

Tiết kiệm bộ nhớ của bạn sẽ thay đổi tùy thuộc vào số lượng và kích thước của chuỗi trong plugin của bạn. Tôi đặt cùng một plugin có thể nhanh chóng xác định sử dụng bộ nhớ dựa trên số lượng và kích thước của chuỗi trong plugin của bạn. Theo mặc định nó được thiết lập để sử dụng chuỗi đóng gói, để có được kết quả của việc sử dụng chuỗi giải nén, bình luận dòng # xác định PACKED_STRINGS.


Đây là một số kết quả mà tôi đã đưa ra sử dụng một số khác nhau của chuỗi, tất cả với một kích thước của 512. Tất cả kết quả là giá trị của tổng số yêu cầu 'khi biên dịch. Tôi cũng đã làm một thử nghiệm bằng cách sử dụng kích thước 33 chuỗi và tiết kiệm có thể bắt đầu được chú ý tại 4 + chuỗi.
Code:
NUM_STRINGS = 1
PACKED = 19756
UNPACKED = 19088
Net savings = -668 bytes [Uses more memory when packed]

NUM_STRINGS = 5
PACKED = 21820
UNPACKED = 27296
Net savings = 5476 bytes

NUM_STRINGS = 10
PACKED = 24400
UNPACKED = 37556
Net savings = 13156 bytes

NUM_STRINGS = 20
PACKED = 29560
UNPACKED = 58076
Net savings = 28516 bytes

NUM_STRINGS = 30
PACKED = 34720
UNPACKED = 78596
Net savings = 43876 bytes

NUM_STRINGS = 50
PACKED   = 45040
UNPACKED = 119636
Net savings = 74596 bytes

NUM_STRINGS = 100
PACKED = 70840
UNPACKED = 222236
Net savings = 151396 bytes
PHP Code:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "Packed vs Unpacked"
#define VERSION "1.0"
#define AUTHOR "bugsy"

#define PACK_STRINGS

#define NUM_STRINGS    20
#define MAX_STRING_SIZE    512

#if defined PACK_STRINGS

new g_szUnpackBuffer[MAX_STRING_SIZE];
new 
g_szStrings[NUM_STRINGS][MAX_STRING_SIZE char]

#else
new g_szStrings[NUM_STRINGS][MAX_STRING_SIZE]
#endifpublic plugin_init()
{
    
register_plugin(PLUGINVERSIONAUTHOR)
}

public 
plugin_cfg()
{
    for ( new 
iTest iTest NUM_STRINGS iTest++ )
    {
        
#if defined PACK_STRINGS
        
g_szStrings[iTest] = !"Packed strings"  
        
strunpackg_szStrings[iTest] , g_szUnpackBuffer );
        
server_print"%d = %s" iTest g_szUnpackBuffer );
        
#else
        
g_szStrings[iTest] = "Unpacked strings";
        
server_print"%d = %s" iTest g_szStrings[iTest] );
        
#endif
    
}
}
#if defined PACK_STRINGSpublic strunpackszPacked[] , szUnpacked[] )
{   
    new 
i;

    while((
szUnpacked[i] = szPacked{i++})){}
}
#endif  
Padding - Đệm

Từ một chuỗi đóng gói vẫn sử dụng ô nhớ 4-byte, bạn sẽ thường nhận được 1-3 byte của không gian lãng phí. Điều này là bởi vì bạn không thể chỉ có một ô nhớ một phần. Giả sử bạn muốn để lưu trữ 5 ký tự trong một chuỗi đóng gói. Về mặt lý thuyết bạn chỉ cần 5 byte phải không? vì đó là những gì hướng dẫn này đã được giải thích. Có, bạn chỉ cần 5 byte cho việc lưu trữ của chuỗi của bạn nhưng bạn sẽ cần 2 ô nhớ từ 1 ô nhớ chỉ có thể giữ 4 ký tự. Trong trường hợp này chúng ta sẽ có 4 byte được sử dụng trong các tế bào đầu tiên trong 4 chữ cái đầu tiên và sau đó chỉ sử dụng 1 byte trong tế bào thứ hai cho các thư còn lại, cộng với 1 ô thêm cho các ký tự null. Còn sót lại 2 tế bào này được gọi là "đệm" và sẽ vẫn có sản phẩm nào giữ 0 của. Thời gian duy nhất này sẽ không xảy ra là khi kích thước chuỗi của bạn là chia hết cho 4.

Dưới đây là một số kịch bản AMX-X mẫu sử dụng chuỗi đóng gói

PHP Code:
//This will declare a packed and unpacked string, display the values in
//each cell (which are identical) and then display the size of each string
//(in cells) at the end.

//The result: Same data 0 = 0 -> Same data 31 = 31
//Packed Size = 9 cells
//Unpacked Size = 33 cells
//Why is the packed 9 cells? See Padding section above.
new szPacked[33 char];
new 
szUnpacked[33];

for ( new 
33 i++ )
{
    
szPacked{i} = i;
    
szUnpacked[i] = i;
    
server_print"Same data %d = %d" szPacked{i} , szUnpacked[i] );
}
    
server_print"Packed Size = %d cells" sizeof szPacked );server_print"Unpacked Size = %d cells" sizeof szUnpacked );  
PHP Code:
//This will print out the ascii values for each character
//in the string "Packed"
new szPacked[7 char] = !"Packed";

for ( new 
i++ )
    
server_print"%d" szPacked{i} );
        
//This will print the ascii values for "Packed": 80, 97, 99, 107, 101, 100, 0
//P=80 a=97 c=99 k=107 e=101 d=100 NULL=0  
PHP Code:
//Define a packed array used to store bool values for playersnew g_szOnline[33 char];

public 
client_putinserver(id)
{
    
g_szOnline{id} = 1;
}

public 
client_disconnect(id)
{
    
g_szOnline{id} = 0;
}

public 
YourFunc(id)
{
    if ( !
g_szOnline{id} )
        
//user not online}  

0 nhận xét:

Post a Comment