Arameus wrote:It's a terrible way to do it because you still go through each character, just instead of printing them, you add them to a string and them print them, which is arbitrary anyway, since a string is just an array of characters. Also, you have to use one more variable. Now, instead of just having all the characters, you the an array of all the characters plus the actual variable that the character is in.
A string is indeed just an array of characters.
The usage of one more variable is arbitrary because a variable is just an identifier to a segment of memory.
Arameus wrote:Finally, you concatenate two strings EACH iteration, which is a lot more resource expensive than just printing them each iteration (which you still do in either version).
Any form of IO will always be an order of magnitude or 2 slower then memory access (in the case of small data as were handling it 3-4 orders of magnitude slower then CPU cache and register access). In which case memory manipulations become inconsequential in comparison to the actual IO. Meaning the appending of one byte is the more efficient of the two.
Also,
Function call overhead is typically more expensive then appending a single byte of information to a segment of memory. As with a function call much more data must be pushed to the stack (all the arguments, register states etc) which is significant compared to one lonely byte of data.
That in mind, sending the entire string to stdout all at once should allow your kernel to perform IO buffering much more efficiently and that alone should improve performance by an order of magnitude.
fabianhjr wrote:If you move trough my pseudocode you will noticed that the string is appended it's first member to the end and printing the whole string in each cycle.(2 operations) + jump and increase i(4). That makes a total complexity of O(num*4).(@thetan am I right?)
- Code: Select all
num = 5
char = 3
string = ''.join(char)
for i in range(num):
print string
string = string[:] + string[0]
Well, it depends on how you would go about abstracting big-o. Iteratively (given that strings in python track head + tail) i don't see why it wouldn't be an O(n) operation iteratively. Which is the way big-o is normally used to display the complexity of the solution. If you want to dissect on a per iteration basis though then yeah, you big-o would hold true for a per-iteration representation.
Anyways, i'm pulling an all nighter at the office and i have nothing better to do tonight so i'll compile some different solutions, and post them with time benchmarks, memory utilization benchmarks and cache hit benchmarks. In other words, i'll be having lots of fun with Valgrind tonight <3
EDIT1:
Ok, here are some basic simple implementations in C. Ran it through a quick benchmark and the difference is largely negligible.I'm willing to place good money that the bottleneck is the actual IO. Anways, heres what i got so far.
loopdeloop
- Code: Select all
#include <stdio.h>
#include <stdlib.h>
void loopdeloop(char c, int m)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = -1; j < i; j++) printf("%c", c);
printf("\n");
}
}
int main (int argc, char *argv[])
{
int i;
for (i = 0; i < 1000; i++) loopdeloop('a', 75);
return 0;
}
stack
- Code: Select all
#include <stdio.h>
#include <stdlib.h>
void stack(char c, int m)
{
char s[512];
int i, j;
// impose arbitrary stack limit
if (m >= 512) return;
for (i = 0; i < m;)
{
s[i] = c;
s[++i] = '\0';
printf("%s\n", s);
}
}
int main (int argc, char *argv[])
{
int i;
for (i = 0; i < 1000; i++) stack('a', 75);
return 0;
}
and the results are as follows:
- Code: Select all
$time ./loopdeloop
...
...
...
real 0m17.679s
user 0m0.204s
sys 0m0.196s
$time ./stack
...
...
...
real 0m16.941s
user 0m0.064s
sys 0m0.224s
Whatever, this is largely unfair though so should be taken with a grain of salt, i'll remove the IO and then well get some usable benchmarks. just give me a minute ..............