--- a/CRC32Stream.st Sat Mar 23 11:48:37 2019 +0100
+++ b/CRC32Stream.st Sat Mar 23 11:48:47 2019 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 2003 by eXept Software AG
All Rights Reserved
@@ -143,71 +141,73 @@
"
expect 60C1D0A0
- [exBegin]
+ [exBegin]
self information:(CRC32Stream hashValueOf:'resume') hexPrintString
- [exEnd]
+ [exEnd]
expect 16r60C1D0A0
- [exBegin]
+ [exBegin]
self information:(CRC32Stream new
- nextPut:$r;
- nextPut:$e;
- nextPut:$s;
- nextPut:$u;
- nextPut:$m;
- nextPut:$e;
- hashValue) hexPrintString
- [exEnd]
+ nextPut:$r;
+ nextPut:$e;
+ nextPut:$s;
+ nextPut:$u;
+ nextPut:$m;
+ nextPut:$e;
+ hashValue) hexPrintString
+ [exEnd]
expect 16r70E46888:
- [exBegin]
+ [exBegin]
self information:(CRC32Stream hashValueOf:#[1 2 3 4 5 6 7]) hexPrintString
- [exEnd]
+ [exEnd]
expect 16r8CD04C73:
- [exBegin]
+ [exBegin]
self information:((CRC32Stream hashValueOf:#[16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
- 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
- 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
- 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
- [exEnd]
+ 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+ 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+ 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
+ [exEnd]
timing throughput:
230Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
- [exBegin]
+ [exBegin]
|hashStream n t|
hashStream := CRC32Stream new.
n := 2000000.
t := Time millisecondsToRun:[
- n timesRepeat:[
- hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
- ].
- ].
+ n timesRepeat:[
+ hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+ ].
+ ].
t := (t / 1000) asFloat.
Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
- Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
- Transcript show:(n*50/1024 / t); showCR:' Kb/s'
- [exEnd]
+ Transcript show:t; show:' seconds for '; show:(50*n/1024/1024) asFloat; showCR:' Mb'.
+ Transcript show:(n*50/1024/1024 / t); showCR:' Mb/s'
+ [exEnd]
500Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
- [exBegin]
- |hashStream n t|
+ [exBegin]
+ |hashStream s n t l|
hashStream := CRC32Stream newCastagnoli.
n := 2000000.
+ s := '12345678901234567890123456789012345678901234567890'.
+ l := s size.
t := Time millisecondsToRun:[
- n timesRepeat:[
- hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
- ].
- ].
+ n timesRepeat:[
+ hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+ ].
+ ].
t := (t / 1000) asFloat.
Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
- Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
- Transcript show:(n*50/1024 / t); showCR:' Kb/s'
- [exEnd]
+ Transcript show:t; show:' seconds for '; show:(l*n/1024/1024) asFloat; showCR:' Mb'.
+ Transcript show:(n*l/1024/1024 / t); showCR:' Mb/s'
+ [exEnd]
the real speed is shown with longer inputs...
- [exBegin]
+ [exBegin]
|hashStream n t l s|
hashStream := CRC32Stream newCastagnoli.
@@ -215,42 +215,42 @@
s := '1234567890' ,* 10000.
l := s size.
t := Time millisecondsToRun:[
- n timesRepeat:[
- hashStream nextPutAll:s
- ].
- ].
+ n timesRepeat:[
+ hashStream nextPutAll:s
+ ].
+ ].
t := (t / 1000) asFloat.
Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
- Transcript show:t; show:' seconds for '; show:(l*n/1024) asFloat; showCR:' Kb'.
+ Transcript show:t; show:' seconds for '; show:(l*n/1024/1024) asFloat; showCR:' Mb'.
Transcript show:(n*l/1024/1024 / t); showCR:' Mb/s'
- [exEnd]
+ [exEnd]
test vectors from https://tools.ietf.org/html/rfc3720#page-217:
expect 0
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:'') hexPrintString
- [exEnd]
+ [exEnd]
expect C1D04330
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:'a') hexPrintString
- [exEnd]
+ [exEnd]
expect E3069283
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:'123456789') hexPrintString
- [exEnd]
+ [exEnd]
expect 8A9136AA
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:0)) hexPrintString
- [exEnd]
+ [exEnd]
expect 62a8ab43
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:16rFF)) hexPrintString
- [exEnd]
+ [exEnd]
expect 46dd794e
- [exBegin]
+ [exBegin]
self information:(CRC32Stream newCrc32c hashValueOf:(0 to:31) asByteArray) hexPrintString
- [exEnd]
+ [exEnd]
"
! !
@@ -427,110 +427,119 @@
and works only for the castagnoli polynom"
%{ /* NOCONTEXT */
+#define HAS_CRC
#if defined(HAS_CRC)
+ int len, offs;
+
+ // fetch first - check later
+ len = __intVal(count);
+ offs = __intVal(start) - 1;
+
if (__bothSmallInteger(count, start)) {
- int len, offs;
- int objSize;
- unsigned char *extPtr;
-
- len = __intVal(count);
- offs = __intVal(start) - 1;
-
- if (__isExternalBytesLike(anObject)) {
- OBJ sz = __externalBytesSize(anObject);
+ int objSize;
+ unsigned char *extPtr;
- extPtr = (unsigned char *)__externalBytesAddress(anObject);
- if (__isSmallInteger(sz)) {
- objSize = __intVal(sz);
- } else {
- objSize = 0; /* unknown */
- }
- } else {
- int nInstVars, nInstBytes;
- OBJ oClass = __Class(anObject);
+ // the most common first
+ if (__isStringLike(anObject)) {
+ objSize = __stringSize(anObject);
+ extPtr = (unsigned char *)__stringVal(anObject);
+ } else if (__isByteArray(anObject)) {
+ objSize = __byteArraySize(anObject);
+ extPtr = (unsigned char *)__byteArrayVal(anObject);
+ } else if (__isExternalBytesLike(anObject)) {
+ OBJ sz = __externalBytesSize(anObject);
+
+ extPtr = (unsigned char *)__externalBytesAddress(anObject);
+ if (__isSmallInteger(sz)) {
+ objSize = __intVal(sz);
+ } else {
+ objSize = 0; /* unknown */
+ }
+ } else {
+ int nInstVars, nInstBytes;
+ OBJ oClass = __Class(anObject);
- switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
- case BYTEARRAY:
- case WORDARRAY:
- case LONGARRAY:
- case SWORDARRAY:
- case SLONGARRAY:
- case FLOATARRAY:
- case DOUBLEARRAY:
- break;
- default:
- goto bad;
- }
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = __OBJS2BYTES__(nInstVars);
- // nInstBytes is the number of bytes occupied by pointer instance variables
- // subtract from size and add to byte-pointer
- objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
- extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
- }
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ case WORDARRAY:
+ case LONGARRAY:
+ case SWORDARRAY:
+ case SLONGARRAY:
+ case FLOATARRAY:
+ case DOUBLEARRAY:
+ break;
+ default:
+ goto bad;
+ }
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = __OBJS2BYTES__(nInstVars);
+ // nInstBytes is the number of bytes occupied by pointer instance variables
+ // subtract from size and add to byte-pointer
+ objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
+ extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
+ }
- if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
- unsigned int _crc;
- unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
- unsigned char *cp = extPtr+offs;
- unsigned int n = len;
+ if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
+ unsigned int _crc;
+ unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
+ unsigned char *cp = extPtr+offs;
+ unsigned int n = len;
- if (__isSmallInteger(__INST(crc))) {
- _crc = (unsigned int) (__intVal( __INST(crc) ));
- } else {
- _crc = __unsignedLongIntVal( __INST(crc) );
- }
+ _crc = (unsigned int) (__intVal( __INST(crc) ));
+ if (!__isSmallInteger(__INST(crc))) {
+ _crc = __unsignedLongIntVal( __INST(crc) );
+ }
# if __POINTER_SIZE__ == 8
- if (((unsigned INT)cp & 7) == 0) {
- // longword aligned
- for ( ; n >= 32 ; n -= 32, cp += 32) {
- unsigned INT w0 = ((unsigned INT *)cp)[0];
- unsigned INT w1, w2, w3;
+ if (((unsigned INT)cp & 7) == 0) {
+ // longword aligned
+ for ( ; n >= 32 ; n -= 32, cp += 32) {
+ unsigned INT w0 = ((unsigned INT *)cp)[0];
+ unsigned INT w1, w2, w3;
- _crc = __crc32_u64(_crc, w0);
- w1 = ((unsigned INT *)cp)[1];
- _crc = __crc32_u64(_crc, w1);
- w2 = ((unsigned INT *)cp)[2];
- _crc = __crc32_u64(_crc, w2);
- w3 = ((unsigned INT *)cp)[3];
- _crc = __crc32_u64(_crc, w3);
- }
- for ( ; n >= 8 ; n -= 8, cp += 8) {
- _crc = __crc32_u64(_crc, ((unsigned INT *)cp)[0]);
- }
- }
+ _crc = __crc32_u64(_crc, w0);
+ w1 = ((unsigned INT *)cp)[1];
+ _crc = __crc32_u64(_crc, w1);
+ w2 = ((unsigned INT *)cp)[2];
+ _crc = __crc32_u64(_crc, w2);
+ w3 = ((unsigned INT *)cp)[3];
+ _crc = __crc32_u64(_crc, w3);
+ }
+ for ( ; n >= 8 ; n -= 8, cp += 8) {
+ _crc = __crc32_u64(_crc, ((unsigned INT *)cp)[0]);
+ }
+ }
# endif // __POINTER_SIZE__ == 8
- if (((unsigned INT)cp & 3) == 0) {
- // word aligned
- for ( ; n >= 4 ; n -= 4, cp += 4) {
- _crc = __crc32_u32(_crc, ((unsigned int *)cp)[0]);
- }
- }
- for ( ; n >= 4 ; n -= 4, cp += 4) {
- _crc = __crc32_u8(_crc, cp[0]);
- _crc = __crc32_u8(_crc, cp[1]);
- _crc = __crc32_u8(_crc, cp[2]);
- _crc = __crc32_u8(_crc, cp[3]);
- }
- while (n-- > 0) {
- unsigned char ch = *cp++;
+ if (((unsigned INT)cp & 3) == 0) {
+ // word aligned
+ for ( ; n >= 4 ; n -= 4, cp += 4) {
+ _crc = __crc32_u32(_crc, ((unsigned int *)cp)[0]);
+ }
+ }
+ for ( ; n >= 4 ; n -= 4, cp += 4) {
+ _crc = __crc32_u8(_crc, cp[0]);
+ _crc = __crc32_u8(_crc, cp[1]);
+ _crc = __crc32_u8(_crc, cp[2]);
+ _crc = __crc32_u8(_crc, cp[3]);
+ }
+ while (n-- > 0) {
+ unsigned char ch = *cp++;
- _crc = __crc32_u8(_crc, ch);
- }
+ _crc = __crc32_u8(_crc, ch);
+ }
- if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
- __INST(crc) = __MKSMALLINT(_crc);
- } else {
- // this code fails with gcc 4.7.2:
- // __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
- OBJ temp = __MKUINT(_crc);
- __INST(crc) = temp; __STORESELF(crc);
- }
+ if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
+ __INST(crc) = __MKSMALLINT(_crc);
+ } else {
+ // this code fails with gcc 4.7.2:
+ // __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
+ OBJ temp = __MKUINT(_crc);
+ __INST(crc) = temp; __STORESELF(crc);
+ }
- RETURN (count);
- }
+ RETURN (count);
+ }
}
bad: ;
#endif
@@ -538,6 +547,7 @@
self primitiveFailed
"Created: / 17-03-2019 / 16:44:27 / Claus Gittinger"
+ "Modified: / 23-03-2019 / 10:11:14 / Claus Gittinger"
! !
!CRC32Stream class methodsFor:'documentation'!
@@ -549,3 +559,4 @@
version_CVS
^ '$Header$'
! !
+