Created
September 18, 2010 02:17
-
-
Save d0k/585257 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#ifdef __SSE2__ | |
#include <emmintrin.h> | |
#endif | |
static const char *SkipToNewline(const char *CurPtr, const char *BufferEnd) { | |
unsigned char C = *CurPtr; | |
if (CurPtr + 24 < BufferEnd) { | |
// While not aligned to a 16-byte boundary. | |
while (C != '\n' && C != '\r' && ((intptr_t)CurPtr & 0x0F) != 0) | |
C = *CurPtr++; | |
if (C == '\n' || C == '\r') return CurPtr; | |
#ifdef __SSE2__ | |
__m128i NLs = _mm_set1_epi8('\n'); | |
__m128i CRs = _mm_set1_epi8('\r'); | |
while (CurPtr+16 <= BufferEnd) { | |
__m128 Data = *(__m128i*)CurPtr; | |
__m128 CmpNL = _mm_cmpeq_epi8(Data, NLs); | |
__m128 CmpCR = _mm_cmpeq_epi8(Data, CRs); | |
__m128 Or = _mm_or_si128(CmpNL, CmpCR); | |
if (_mm_movemask_epi8(Or) != 0) | |
break; | |
CurPtr += 16; | |
} | |
#else | |
while (CurPtr+4 < BufferEnd && | |
CurPtr[0] != '\n' && CurPtr[0] != '\r' && | |
CurPtr[1] != '\n' && CurPtr[1] != '\r' && | |
CurPtr[2] != '\n' && CurPtr[2] != '\r' && | |
CurPtr[3] != '\n' && CurPtr[3] != '\r') | |
CurPtr += 4; | |
#endif | |
// It has to be one of the bytes scanned, increment to it and read one. | |
C = *CurPtr++; | |
} | |
// Loop to scan the remainder. | |
while (C != '\n' && C != '\r' && C != '\0') | |
C = *CurPtr++; | |
return CurPtr; | |
} | |
int main(int argc, char *argv[]) { | |
FILE *fd = fopen(argv[1], "r"); | |
fseek(fd, 0, SEEK_END); | |
unsigned long len = ftell(fd); | |
fseek(fd, 0, SEEK_SET); | |
char *buf = malloc(len+1); | |
char *end = buf + len; | |
fread(buf, 1, len, fd); | |
*end = 0; | |
const char *ptr = buf-1; | |
unsigned lines = 0; | |
while ((ptr = SkipToNewline(ptr+1, end)) != end) { | |
printf("%zu\n", ptr-buf); | |
lines++; | |
} | |
printf("\n%u\n", lines); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment