Programação, diversão e arte. Por Ricardo Giaviti
Posts tagged C++
Configurando ambiente de desenvolvimento C++ no Windows com Eclipse e MinGW
May 11th
O Eclipse é uma das melhores IDEs de desenvolvimento Java no mercado. O que pouca gente sabe, é que ela também pode ser usada para desenvolvimento de aplicações utilizando o C++. Nesse pequeno tutorial, mostrarei como instalar o compilador C++ para Windows (MinGW) e utilizar o Eclipse para trabalhar com esse compilador.
O compilador MinGW (Minimalist GNU for Windows) é uma versão portada para Microsoft Windows do conjunto de ferramentas GNU. Este software inclui um conjunto de arquivos cabeçalho para a API do Windows que permite aos desenvolvedores usar o GCC para criar programas nativos em Windows sem precisar contar com uma emulação em tempo real de um sistema Unix-like.
Ambiente usado nesse tutorial:
- Windows XP SP2
- Eclipse 3.4 – Ganymede C++
O primeiro passo é baixar o Eclipse para C++. Para isso, vá ao site oficial do Eclipse (http://www.eclipse.org), clique em “Download Eclipse” e baixe a última versão do “Eclipse IDE for C/C++ Developers“. O Eclipse vem em uma pacote ZIP (quando Windows) com aproximadamento 68MB. Feito o download do Eclipse, descompacte o arquivo ZIP. Agora vamos ao próximo passo.
Nesse segundo passo, vamos baixar o MinGW, que é o compilador que utilizaremos. Acessem o site do MinGW (http://www.mingw.org), vá em “Downloads” e baixe a última versão do “Automated MinGW Installer“. Enquanto esse artigo esta sendo escrito, a última versão é a MinGW 5.1.4 de 26/04/2008. O arquivo é pequeno porque toda a instalação será feita online. Ele baixará todos os arquivos necessários na hora da instalação.
Existe alguns detalhes para se instalar o MinGW. Duplo clique no instalador e vamos começar a instalação. Você deverá estar conectado a Internet para instalar o MinGW com sucesso. Na primeira tela, clique em “Next“. Na segunda, marque a opção “Download and install“, igual na figura abaixo.
Depois clique em “I Agree” para aceitar a licensa GPL e na tela de escolha de pacote (Choose Package), marque a opção “Current“, para instalar a versão estável atual do MinGW.
- Previous: Versão estável anterior;
- Current: Versão atual estável;
- Candidate: Versão futura porém instável;
Na escolha de componentes (Choose Components), você deverá obrigatoriamente marcar as opções:
- MinGW base tools;
- g++ compiler
As outras opções (g77 compiler, Ada compiler…) são opcionais. Elas não são necessárias para o que pretendemos fazer com esse tutotial. Instale se você quiser.
Clique em “Next” e escolha o diretório de instalação. O diretório padrão e recomendado é o “C:\MinGW“. Avance mais uma vez e o instalador irá começar a fazer o download dos componentes e a instalação dos mesmos.
Após terminar, finalize o instalador e abra o Eclipse (que você descompactou no primeiro passo). Para rodar o Eclipse você irá precisar da JRE instalada. Caso você não tenha a JRE, basta fazer o download aqui: http://java.sun.com/javase/downloads/index.jsp. Selecione a opção: “Java SE Runtime Environment (JRE)“.
Com o Eclipse aberto, teremos a seguinte tela:
Até aí tudo certo? Agora vamos criar o nosso projetinho C++ de exemplo para ver se está tudo OK e se a compilação está funcionando. Para criar o projeto faça: “File > New > C++ Project“. Digite um nome para seu projeto e escolha a opção “Hello World C++ Project“. Verifique se o MinGW aparece no Toolchains. Abaixo segue uma figura para você ter uma referência:
Agora clique em “Finish” e vamos testar. O projeto será criado e você pode fechar essa tela de “Welcome” que aparece quando se inicia o Eclipse. Repare que o projeto criado está no lado esquerdo do Eclipse. Essa janela onde fica os projetos é chamada de “Project Explorer“. Expanda seu projeto, vá na pasta src e duplo clique no arquivo “Teste.cpp“. Você terá um código igual ao abaixo:
//============================================================================ // Name : Teste.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! return 0; }
Abaixo segue uma screenshot do Eclipse para você ter uma referência de como estarão as coisas nesse momento.
Agora vamos rodar o projeto. Para compilar e rodar esse projeto, clique no “Play” na barra de ferramentas lá em cima no Eclipse. Se tudo der certo, no console dele irá aparecer “!!!Hello World!!!“. Se aparecer, quer dizer que deu tudo certo e seu Eclipse está prontinho para ser usado como uma IDE de desenvovlimento C++.
Existem muitos livros e muitos tutoriais na Internet sobre C++. De uma pesquisada no Google sobre o assunto e você verá quanta informação você achará. Até a próxima e bons estudos.
Fontes:
Explicação sobre o MinGW: http://pt.wikipedia.org/wiki/MinGW
Comparação de desempenho entre linguagens de programação
Jul 27th
No dia 08/07/2008 o blog var/log/mind publicou uma comparação de desempenho entre algumas linguagens de programação. As linguagens testadas pelo blog foram C++, JAVA, Ruby, JRuby, Python, Jython, Groovy e PHP. Esse tema gerou até um bafafá na blogosfera nacional e internacional.
A tipo de benchmark feito pelo é blog foi bem simples e baseado em um pedaço de lógica onde é medido o tempo de cada iteração num total de 100000 iterações.
O mais espantoso foi que JAVA obteve um desempenho melhor do que C++. Esse resultado me deixou com uma pulga atrás da orelha porque sempre acreditei (mas nunca havia testado) de que C++ por ser somente compilado seria bem mais rápido do que JAVA que é compilado e interpretado pela JVM.
Então resolvi fazer o mesmo teste que o blog var/log/mind fez. Utilizei os mesmos códigos disponibilizados por ele e rodei eles em minha máquina. Somente não testei Python, Jython e o Groovy.
Ambiente de Testes
Meu ambiente de testes difere do ambiente de testes do var/log/mind (veja a tabela mais abaixo), assim como versões de compiladores e interpretadores. Abaixo segue o meu ambiente de testes e mais um pouco abaixo as versões dos compiladores e interpretadores usados no teste.
Meu ambiente:
- Processador: AMD 4200+ X2 64 Bits
- Memória: 3GB RAM
- SO: Windows XP SP2 Professional
As diferenças entre o ambiente de teste original do var/log/mind e o meu ambiente de teste:
| MeuPost.com | var/log/mind | |
|---|---|---|
| Processador | AMD 4200+ X2 64 Bits | Intel® Core™ Duo CPU T2600 @ 2.16GHz |
| Memória | 3GB RAM | 2GB |
| SO: | Windows XP SP2 Professional | Ubuntu Gutsy Gibbon 7.10 |
Compiladores e Interpretadores usados:
- C++: MinGW32 GCC: 3.4.2
- JAVA 1.6
- Ruby 1.8.6-26
- JRuby 1.1
- PHP 5.2.3
Teste:
Para realizar o teste rodei 5 vezes o código de cada linguagem diferente e anotei todos os resultados em nanossegundos. Depois tirei a média dos resultados.
Resultados
Seguinte a tendência dos resultados, em meu ambiente JAVA também foi superior ao C++. Os resultados também mostraram que o Python está mais maduro que Ruby embora nas últimas versões do Ruby (1.9) o desempenho tenha melhorado muito.
Outro fato interessante é que o JRuby está também mais rápido que Ruby. Já o PHP mostra a força de sua maturidade e popularidade ganhando tanto do Ruby como do JRuby, isso em meu ambiente, porque no var/log/mind tanto o Ruby como o JRuby ganharam do PHP.
Acredito que esse desempenho superior do Ruby no var/log/mind está diretamente associado ao sistema operacional. O Ruby está rodando muito mais rápido em ambientes Linux do que em Windows.
Abaixo segue a tabela de resultados:
| Iteração 1 | Iteração 2 | Iteração 3 | Iteração 4 | Iteração 5 | Média | Total | |
| C++ | 12000 | 12000 | 12000 | 12000 | 12000 | 12000 | 60000 |
| Java | 1509 | 1369 | 1384 | 1376 | 1385 | 1404,6 | 7023 |
| Ruby | 491990 | 493750 | 494690 | 493280 | 494840 | 444232 | 2468550 |
| Jruby | 244040 | 246360 | 243830 | 243450 | 246750 | 244886 | 1224430 |
| PHP | 125200 | 125030 | 124880 | 124890 | 124900 | 124980 | 624900 |
| 1 segundo = 1000000 microssegundo = 1000000000 nanossegundo | |||||||
Para facilitar a visualização dos resultados, abaixo segue um gráfico com o resultado do teste:
Códigos
Abaixo segue os códigos utilizados nos testes. São os mesmos do var/log/mind com uma única diferença no código C++. Como o var/log/mind usou o Linux, ele usou a função gettimeofday(), em Windows essa função não existe, então eu como não sou um programador C++, achei essa função no Blog OpenAsthra e coloquei no código.
Todos os outros códigos são exatamente iguais.
C++
#include <time.h> #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; int gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ft; unsigned __int64 tmpres = 0; static int tzflag = 0; if (NULL != tv) { GetSystemTimeAsFileTime(&ft); tmpres |= ft.dwHighDateTime; tmpres <<= 32; tmpres |= ft.dwLowDateTime; tmpres /= 10; /*convert into microseconds*/ /*converting file time to unix epoch*/ tmpres -= DELTA_EPOCH_IN_MICROSECS; tv->tv_sec = (long)(tmpres / 1000000UL); tv->tv_usec = (long)(tmpres % 1000000UL); } if (NULL != tz) { if (!tzflag) { _tzset(); tzflag++; } tz->tz_minuteswest = _timezone / 60; tz->tz_dsttime = _daylight; } return 0; } #define TEST #ifdef TEST #endif class Person { public: Person(int count) : _next(NULL), _prev(NULL) { _count = count; } int shout(int shout, int nth) { if (shout < nth) return (shout + 1); _prev->_next = _next; _next->_prev = _prev; return 1; } int count() { return _count; } Person* next() { return _next; } void next(Person* person) { this->_next = person ; } Person* prev() { return _prev; } void prev(Person* person) { this->_prev = person; } private: int _count; Person* _next; Person* _prev; }; class Chain { public: Chain(int size) : _first(NULL) { Person* current = NULL; Person* last = NULL; for(int i = 0 ; i < size ; i++) { current = new Person(i); if (_first == NULL) _first = current; if (last != NULL) { last->next(current); current->prev(last); } last = current; } _first->prev(last); last->next(_first); } Person* kill(int nth) { Person* current = _first; int shout = 1; while(current->next() != current) { Person* tmp = current; shout = current->shout(shout,nth); current = current->next(); if (shout == 1) { delete tmp; } } _first = current; return current; } Person* first() { return _first; } private: Person* _first; }; int main(int argc, char** argv) { int ITER = 100000; Chain* chain; struct timeval start, end; gettimeofday(&start,NULL); for(int i = 0 ; i < ITER ; i++) { chain = new Chain(40); chain->kill(3); delete chain; } gettimeofday(&end,NULL); fprintf(stdout,"Time per iteration = %d microsecondsnr", (((end.tv_sec - start.tv_sec) * 1000000) + (end.tv_usec - start.tv_usec)) / ITER); //fprintf(stdout,"Last man standing is %dnr", (chain->first()->count() + 1)); return 0; } }
JAVA:
package com.dnene.josephus; public class Chain { private Person first = null; public Chain(int size) { Person last = null; Person current = null; for (int i = 0; i < size; i++) { current = new Person(i); if (first == null) first = current; if (last != null) { last.setNext(current); current.setPrev(last); } last = current; } first.setPrev(last); last.setNext(first); } public Person kill(int nth) { Person current = first; int shout = 1; while (current.getNext() != current) { shout = current.shout(shout, nth); current = current.getNext(); } first = current; return current; } public Person getFirst() { return first; } public static void main(String[] args) { int ITER = 100000; long start = System.nanoTime(); for (int i = 0; i < ITER; i++) { Chain chain = new Chain(40); chain.kill(3); } long end = System.nanoTime(); System.out.println("Time per iteration = " + ((end - start) / (ITER)) + " nanoseconds."); } } package com.dnene.josephus; public class Person { int count; private Person prev = null; private Person next = null; public Person(int count) { this.count = count; } public int shout(int shout, int deadif) { if (shout < deadif) return (shout + 1); this.getPrev().setNext(this.getNext()); this.getNext().setPrev(this.getPrev()); return 1; } public int getCount() { return this.count; } public Person getPrev() { return prev; } public void setPrev(Person prev) { this.prev = prev; } public Person getNext() { return next; } public void setNext(Person next) { this.next = next; } }
Ruby / JRuby
class Person attr_reader :count, :prev, :next attr_writer :count, :prev, :next def initialize(count) #puts 'Initializing person : ' + count.to_s() @count = count @prev = nil @next = nil end def shout(shout, deadif) if shout < deadif return shout + 1 end @prev.next = @next @next.prev = @prev return 1 end end class Chain attr_reader :first attr_writer :first def initialize(size) @first = nil last = nil for i in (1..size) current = Person.new(i) if @first == nil @first = current end if last != nil last.next = current current.prev = last end last = current end @first.prev = last last.next = @first end def kill(nth) current = @first shout = 1 while current.next != current shout = current.shout(shout,nth) current = current.next end @first = current return current end end ITER=100000 start = Time.now ITER.times { |i| chain = Chain.new(40) chain.kill(3) } ends = Time.now puts 'Time per iteration = ' + ((ends - start) * 1000000 / ITER).to_s() + " microseconds"
PHP
<?php class Person { function __construct($c) { $this->count = $c; } function getPrev() { return $this->prev; } function setPrev($pr) { $this->prev = $pr; } function getNext() { return $this->next; } function setNext($nxt) { $this->next = $nxt; } function shout($shout, $nth) { if ($shout < $nth) { return $shout + 1; } $this->getPrev()->setNext($this->getNext()); $this->getNext()->setPrev($this->getPrev()); return 1; } } class Chain { var $first; function __construct($size) { for($i = 0; $i < $size ; $i++) { $current = new Person($i); if ($this->first == null) $this->first = $current; if ($last != null) { $last->setNext($current); $current->setPrev($last); } $last = $current; } $this->first->setPrev($last); $last->setNext($this->first); } function kill($nth) { $current = $this->first; $shout = 1; while($current->getNext() !== $current) { $shout = $current->shout($shout,$nth); $current = $current->getNext(); } $this->first = $current; } } $start = microtime(true); $ITER = 100000; for($i = 0 ; $i < $ITER ; $i++) { $chain = new Chain(40); $chain->kill(3); } $end = microtime(true); printf("Time per iteration = %3.2f microsecondsnr",(($end - $start) * 100000 / $ITER)); ?>
É isso pessoal.
Esse tema de desempenho sempre gera polêmica pois sempre há brechas e margens para discussão. Então, quem quiser debater sobre o assunto.
Até a próxima.














Recent Comments