tested and decided against cacheing iconv_open

This commit is contained in:
dockes 2009-01-26 13:27:43 +00:00
parent 4c82cd9c9d
commit 79c1f814f9

View File

@ -40,10 +40,20 @@ using std::string;
#define ICV_P2_TYPE char** #define ICV_P2_TYPE char**
#endif #endif
// We gain approximately 28% exec time for word at a time conversions by
// caching the iconv_open thing. This is probably not worth it.
//#define ICONV_CACHE_OPEN
bool transcode(const string &in, string &out, const string &icode, bool transcode(const string &in, string &out, const string &icode,
const string &ocode, int *ecnt) const string &ocode, int *ecnt)
{ {
#ifdef ICONV_CACHE_OPEN
static iconv_t ic;
static string cachedicode;
static string cachedocode;
#else
iconv_t ic; iconv_t ic;
#endif
bool ret = false; bool ret = false;
const int OBSIZ = 8192; const int OBSIZ = 8192;
char obuf[OBSIZ], *op; char obuf[OBSIZ], *op;
@ -54,12 +64,23 @@ bool transcode(const string &in, string &out, const string &icode,
out.reserve(isiz); out.reserve(isiz);
const char *ip = in.c_str(); const char *ip = in.c_str();
if((ic = iconv_open(ocode.c_str(), icode.c_str())) == (iconv_t)-1) { #ifdef ICONV_CACHE_OPEN
out = string("iconv_open failed for ") + icode if (cachedicode.compare(icode) || cachedocode.compare(ocode)) {
+ " -> " + ocode; #endif
goto error; if((ic = iconv_open(ocode.c_str(), icode.c_str())) == (iconv_t)-1) {
out = string("iconv_open failed for ") + icode
+ " -> " + ocode;
goto error;
}
#ifdef ICONV_CACHE_OPEN
cachedicode.assign(icode);
cachedocode.assign(ocode);
} else {
iconv(ic, 0, 0, 0, 0);
} }
#else
icopen = true; icopen = true;
#endif
while (isiz > 0) { while (isiz > 0) {
size_t osiz; size_t osiz;
@ -89,6 +110,7 @@ bool transcode(const string &in, string &out, const string &icode,
out.append(obuf, OBSIZ - osiz); out.append(obuf, OBSIZ - osiz);
} }
#ifndef ICONV_CACHE_OPEN
if(iconv_close(ic) == -1) { if(iconv_close(ic) == -1) {
out.erase(); out.erase();
out = string("iconv_close failed for ") + icode out = string("iconv_close failed for ") + icode
@ -96,10 +118,13 @@ bool transcode(const string &in, string &out, const string &icode,
goto error; goto error;
} }
icopen = false; icopen = false;
#endif
ret = true; ret = true;
error: error:
#ifndef ICONV_CACHE_OPEN
if (icopen) if (icopen)
iconv_close(ic); iconv_close(ic);
#endif
if (mecnt) if (mecnt)
LOGDEB(("transcode: [%s]->[%s] %d errors\n", LOGDEB(("transcode: [%s]->[%s] %d errors\n",
icode.c_str(), ocode.c_str(), mecnt)); icode.c_str(), ocode.c_str(), mecnt));
@ -124,8 +149,28 @@ using namespace std;
#include "readfile.h" #include "readfile.h"
#include "transcode.h" #include "transcode.h"
// Repeatedly transcode a small string for timing measurements
static const string testword("\xc3\xa9\x6c\x69\x6d\x69\x6e\xc3\xa9\xc3\xa0");
// Without cache 10e6 reps on macpro -> 1.88 S
// With cache -> 1.56
void looptest()
{
cout << testword << endl;
string out;
for (int i = 0; i < 1000*1000; i++) {
if (!transcode(testword, out, "UTF-8", "UTF-16BE")) {
cerr << "Transcode failed" << endl;
break;
}
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
#if 0
looptest();
exit(0);
#endif
if (argc != 5) { if (argc != 5) {
cerr << "Usage: trcsguess ifilename icode ofilename ocode" << endl; cerr << "Usage: trcsguess ifilename icode ofilename ocode" << endl;
exit(1); exit(1);