How could I fix my crap code?

I found some curious phenomenons from vc2010
os : windows xp sp3
compilers : vs2010(express edition) and gcc4.5.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
template<typename unaryOP>
double timeCount(unaryOP op, size_t const LOOP = 1, char const* NAME = "function")
{
  std::clock_t begin, end;
  begin = std::clock();
  for(size_t i = 0; i != LOOP; ++i) op();
  end = std::clock();
  double const RESULT = (end - begin) / static_cast<double>(CLOCKS_PER_SEC);
  size_t const HOUR = static_cast<size_t>(RESULT / 3600);
  size_t const MIN = static_cast<size_t>(RESULT) / 60 - HOUR * 60;
  double const SEC = RESULT - static_cast<double>(MIN * 60 + HOUR * 3600);
  std::cout<<"time of the(hours : min : sec) "<<NAME<<" : "<<HOUR<<" : "<<MIN<<" : "<<SEC;
  std::cout<<"\nloop "<<LOOP<<" times\n";
  return RESULT;
}

void* CFind3(void* begin, void* end, int const VALUE)
{
  while(begin != end)
  {
    if(*(int*)begin == VALUE) break;
    begin = (char*)begin + sizeof(int);
  }
  return begin;
}

void* CFind4(void *begin, size_t const NUM, int const VALUE)
{	
  size_t i = 0;
  for(; i != NUM; ++i)
  {
	if(*(int*)begin == VALUE) break;
	begin = (char*)(begin) + sizeof(int);
  }
  return begin;
}

void testCFind3()
{
	int data[] = {1, 20, 33, 55, 22, 77, 88, 99, 3000, 8880, 800, 777, 345, 976, 345, 222, 111, 0, 77, 88, 99, 1, 2, 3, 20000};
	size_t const NUM = static_cast<size_t>(1E6);
	size_t i = 0;
	for(i = 0; i != NUM; ++i) void *temp = CFind3(&data[0], &data[0] + sizeof(data) / sizeof(*data), 20000);	
}

void testCFind4()
{
	int data[] = {1, 20, 33, 55, 22, 77, 88, 99, 3000, 8880, 800, 777, 345, 976, 345, 222, 111, 0, 77, 88, 99, 1, 2, 3, 20000};
	size_t const NUM = static_cast<size_t>(1E6);
	size_t i = 0;
	for(i = 0; i != NUM; ++i) void *temp = CFind4(&data[0], sizeof(data) / sizeof(*data), 20000);	
}

int main()
{
  timeCount(testCFind3, static_cast<size_t>(1E2), "testCFind3");
  timeCount(testCFind4, static_cast<size_t>(1E2), "testCFind4");

  std::cout<<"system pause"<<std::endl;
  std::cin.get();
  return 0;
}


the time of CFind3 and CFind4 are equivalent on gcc4.5.2(minGW)

the time of CFind3 is 1.984 seconds on vc2010
the time of CFind4 is 0 seconds on vc2010
I guess the penalty is come from this line
 
while(begin != end)


But this kind of code is always seen in generic code of c++
could this mean the generic code generate by vc2010 could be very slow?
Is this a well known defect of vc2010 or it is my mistake to produce this
kind of crap code?Thanks a lot
Last edited on
Did you compile with debug configuration?
Did you compile with debug configuration?

I hope so, but it is a release version
If I didn't make any mistake
the optimization of express edition should be the same as the professional one

ps : I would like to compare with the C style and C++ style at first
So I code CFind3 ~ testCFind4 by C way(except of static_cast)
At first I expected std::find would be as fast as C way or even a little bit faster
But the result on vc2010 make me surprise, I don't know why
Last edited on
You're right. I tried it myself. This is crazy..
I suspect CFind4's time is 0 because the function produces same result as CFind3 and compiler "chooses" not to run CFind4. This is only a guess though.

EDIT: I have not tested anything, and do not know IF they do produce same result.
EDIT2: Isreturn base in CFind4 a typo?
Last edited on
@naraku9333 Nope. Just try switching lines 56, 57.
I switched it, and the results are almost the same
two suggestions:

1. try a simple for() loop with just sizeof(int) and 4 assignment

2. look at the assembler output for your current code or for 1. - this should tell you what's wrong
Isreturn base in CFind4 a typo?

sorry, that was my mistake.I forgot to edit it properly

try a simple for() loop with just sizeof(int) and 4 assignment

thanks, I try it, the result become 0 no matter it is sizeof(int) or 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void* CFind3(void* begin, void* end, int const VALUE)
{  
  while(begin != end)
  {
    //if(*(int*)begin == VALUE) break;
    begin = (char*)begin + sizeof(int);
  }
  return begin;
}

void* CFind4(void *begin, size_t const NUM, int const VALUE)
{	
	size_t i = 0;
	for(; i != NUM; ++i)
	{
		//if(*(int*)begin == VALUE) break;
		begin = (char*)(begin) + sizeof(int);
	}
	return begin;
}


look at the assembler output for your current code or for 1. - this should tell you what's wrong

Looks like this is the only way to know what is wrong
I would try to figure out how to dumb the assembler out(to tell you the truth, I am poor in assembler)
Last edited on
Topic archived. No new replies allowed.