🤔 Para Refletir :
"Fazer um jogo é sempre muito mais difícil do que jogar um jogo..."
- Rafael_Sol_MAKER

RPG Maker MV JavaScript para Iniciantes no RPG Maker MV #10 - Estrutura de Repetição For

Virage Detoldev

Plebeu
Membro
Membro
Juntou-se
17 de Abril de 2017
Postagens
38
Bravecoins
7
Olá pessoal, como vão? Hoje nós vamos estudar sobre a estrutura de repetição For. Vamos lá?


[greenalert]ENTENDENDO SOBRE VARIÁVEL INDEX ANTES DE COMEÇAR[/greenalert]

Antes de falar sobre o FOR, vamos comentar sobre algo não dito quando falamos sobre WHILE/DO, a variável index. Essa variável é geralmente uma variável especial, que é criada para dar término na repetição. Ela não é um tipo novo de variável, nós só chamamos de index para dizer que a única função dela, dentro da repetição, é atingir um valor para terminar a repetição e é com uso dela que sabemos em qual repetição estamos.

Você vai entender melhor sobre isso quando formos falar de arrays, mas sempre-se que o ideal ao se trabalhar com repetições é separar uma variável exclusivamente para a repetição.



[greenalert]O QUE É A REPETIÇÃO FOR[/greenalert]

A repetição for é basicamente a mesma da while, a diferença é a forma como a expressão, que fica dentro dos parênteses é feita. Vamos usar um exemplo com while para entender como o for funciona.

Exemplo:
Código:
var diaSemana = 0;
while (diaSemana < 7) {
++diaSemana;
console.log("Hoje é o " + diaSemana + "º dia da semana.");
}
console.log("A semana acabou...");


Observando o código acima, nós temos alguma etapas ao se criar uma repetição while:
1. Criamos a variável index para dar fim na repetição. Damos o valor 0.
2. Criamos o while, com a expressão que dita que a repetição acontecerá até quando o diaSemana for menor que 7.
3. Criamos o comando que dará +1 a variável a cada repetição.
4. Comando que será repetido, no caso, escrever uma frase no console.
5. Frase que será exibida após a repetição acabar.



Boa parte dos passos acima, quando usamos o FOR, entram dentro de onde as expressões ficam. Vou inserir abaixo o for, sem usar valores, só mostrando o corpo dele:


Código:
for (declaração 1; declaração 2; declaração 3) {
Comando que será repetido
}

Onde:
DECLARAÇÃO 1:
Comando que será executado somente na primeira vez que a repetição acontecer.
DECLARAÇÃO 2: Expressão que dita a condição da repetição.
DECLARAÇÃO 3: Comando que irá ser executado em cada repetição.

Obs.: Apesar da declaração 3 permitir que algo seja executado a cada repetição, geralmente usamos a variável index lá dentro.

Agora vamos criar o exemplo do dia da semana em FOR para você entender o que é feito de diferente:


Código:
for (diaSemana =0; diaSemana <7; ++diaSemana) {
console.log("Hoje é o " + diaSemana + "º dia da semana.");
}
console.log("A semana acabou...");


Dessa forma, verificamos que a variável index é criada dentro da expressão, na declaração 1, e não fora como era no while. Após o ponto e vírgula, temos a expressão que dita a repetição, como acontece no while e por fim, após outro ponto e vírgula, tiramos o incremento (++) de dentro dos comandos e inserimos na expressão. Você observa então que While/Do e For são basicamente a mesma coisa, mas o for te deixa, dentro da expressão, criar uma variável local que será usada só dentro da expressão. Falaremos mais sobre variáveis locais em outro guia.


OBSERVAÇÃO 1: Caso eu não tenha usado a palavra antes, incremento é adicionar valor a algo. No caso de repetições nós geralmente incrementamos +1 na variável index.
OBSERVAÇÃO 2: Existem outras formas de escrever o for, mas falarei delas no futuro. Por enquanto, se atende a entender o básico sobre ele.



É isso por hoje pessoas. Espero que tenha ficado simples. Mais uma vez, algum erro de ortografia ou de explicação pode e deve ser indicado nos comentários. Sem mais, grande abraço.


[redalert]SUMÁRIO DA AULA[/redalert]
- Conceito de Variável Index
- O que é a estrutura de Repetição For
 
Falaremos mais sobre variáveis locais em outro guia.

Só achei que faltou você dizer que variáveis locais deixam o processamento do jogo "mais leve", pois como elas são usadas só ali na hora, o software não precisa ficar "gastando memória" com ela. Tirando esse detalhe, gostei muito do guia! Obrigado!! o/
 
CleanWater comentou:
Falaremos mais sobre variáveis locais em outro guia.

Só achei que faltou você dizer que variáveis locais deixam o processamento do jogo "mais leve", pois como elas são usadas só ali na hora, o software não precisa ficar "gastando memória" com ela. Tirando esse detalhe, gostei muito do guia! Obrigado!! o/

Eu vou falar, é que eu queria deixar separado esse conceito para depois, perto de falar de funções e objetos.
 
Bom resumo sobre o for!

Só gostaria de fazer um acréscimo, pra não dizer que está perfeito. No seu for, você faz o seguinte:
Código:
for (diaSemana =0; diaSemana <7; ++diaSemana)

O ideal seria usar uma declaração do tipo let para a variável de índice. Ou seja:
Código:
for (let diaSemana =0; diaSemana <7; ++diaSemana)

O let (MDN) ali evita vazar a variável pro escopo global, correndo risco de sobrescrever alguma coisa que não devia. A diferença entre let e var, aliás, é que o var define a variável para toda a função, enquanto o let define apenas para o bloco. Isso é especialmente interessante em laços de repetição.



CleanWater comentou:
Só achei que faltou você dizer que variáveis locais deixam o processamento do jogo "mais leve", pois como elas são usadas só ali na hora, o software não precisa ficar "gastando memória" com ela.

giphy.gif

Claro, até porque quando falamos de Javascript (que roda em cima de um fucking browser), essa é uma preocupação (ta bom, pode até ser, mas só em casos fora do comum. Me deixa.)

De fato, não só isso não é relevante, como na verdade está redondamente errado: variáveis GLOBAIS são as que tornam mais leve o processamento. Para uma variável local, precisamos colocar coisas numa pilha de contexto, que precisa ser criada/descartada toda vez que entramos ou saímos de um contexto (a parte do código em que a variável local fica acessível).

Esse tipo de coisa é parte do que torna bem ruim a performance de coisas recursivas com muitas variáveis locais, por exemplo, já que cada chamada de função coloca um contexto enorme na pilha.

Pra variáveis globais, o contexto é global (duh), e portanto só precisa ser criado/descartado uma vez: quando o programa começa e quando termina, respectivamente.

Do ponto de vista de acesso, variáveis globais e locais têm a mesma performance (a menos que a linguagem tenha alguma coisa específica, mas desconheço isso e não parece ter muito sentido).

Recomendo usar variáveis globais? Absolutamente não. Até porque o ganho de performance é risível, e o custo em manutenabilidade do código é bem altinho.



Obs.: talvez você tenha pensado no Garbage Collector, que é responsável por limpar a memória de quando em quando baseado no uso de uma variável. Isso diminui a necessidade de preocupar-nos com gerenciamento de memória, como acontece em linguagens como C/C++, por exemplo.

De toda forma, diferente do que você poderia pensar, limitar o escopo de variáveis pouco afeta o GC.
Mas como assim? Você pode dizer.

Pois é, a menos que o objeto ao qual a variável se refere seja usado em algum outro lugar do código, o GC libera a memória da mesma forma para variáveis locais e globais. Na verdade, ele é agnóstico a variáveis, e gerencia diretamente a alocação de memória.

Inclusive, pode-se dizer que variáveis globais também economizam memória (tempo de alocação, na verdade) ao permitir que objetos sejam reutilizados em vários pontos no código. Claro, tomando as devidas precauções

Recomendo ler o artigo sobre Gerenciamento de memória (que, aliás, dava uma boa aula!) na MDN.
 
Brandt comentou:
O ideal seria usar uma declaração do tipo let para a variável de índice. Ou seja:
Código:
for (let diaSemana =0; diaSemana <7; ++diaSemana)

O let (MDN) ali evita vazar a variável pro escopo global, correndo risco de sobrescrever alguma coisa que não devia. A diferença entre let e var, aliás, é que o var define a variável para toda a função, enquanto o let define apenas para o bloco. Isso é especialmente interessante em laços de repetição.

Nossa, não sabia disso. Vou aproveitar a aula onde eu vou falar mais sobre o for e incluir isso, obrigado Brandt.

Brandt comentou:
Recomendo ler o artigo sobre Gerenciamento de memória (que, aliás, dava uma boa aula!) na MDN.

Adorei a ideia e sim, vou segui-la e dar uma lida e fazer uma aula sobre isso. Obrigado por isso também.
 
[member=78]Brandt[/member] =)

Game Maker: Studio Docs comentou:
A local variable is one that we create for a specific event only and then discard when the event has finished (the only exception to this is in the script resources, where a var declared variable is local to the script and then discarded). Why would we need them? Well, variables take up space in memory and it may be that we are only going to use them for one operation or function in which case we only need to have it in memory for that short time that it's used. This keeps your code base clean and tidy as well as keeping memory space optimised for the things that really need it.

Game Maker: Studio Docs comentou:
A basic description of a global variable is one that, once declared, belongs to no instance in particular and yet can be accessed by all. Just like local variables, global variables must be declared, but unlike a local variable, a global variable remains in memory until the end of the game.

Resumindo… Use variáveis globais somente quando necessário.

Peguei a referência do GM pois foi basicamente nessa engine que "aprendi a programar", mas é claro, o conceito se aplica a outras linguagens e programas também. Essa é apenas uma das técnicas de otimização para um jogo (ou programação de softwares em geral).
 
[member=1673]CleanWater[/member]

Peguei a referência do GM pois foi basicamente nessa engine que "aprendi a programar", mas é claro, o conceito se aplica a outras linguagens e programas também. Essa é apenas uma das técnicas de otimização para um jogo (ou programação de softwares em geral).

220px-Shrug.jpg

Vou dar o crédito que sou leigo quanto ao Game Maker, mas se o assunto é programação de software, boa sorte. Duvido, inclusive, que você tem noção do significado de otimizar um jogo (ou programa em geral).

Disclaimer: Sinceramente, não vejo ganho nenhum em argumentar a respeito desse assunto (até porque, como já disse, usar ou não variáveis locais, principalmente em JS, tanto faz como tanto fez. Eu mesmo não advogo o uso de variáveis globais, mas falar que é por performance é ser tapado demais), mas como já comprei a briga, vamos lá. (Ego? Talvez, mas não sou o único)

Acima de tudo, o principal aqui é: na real, f*da-se. Sugerir falar especificamente sobre performance em variáveis locais é buscar pelo em ovo.



Esclarecimentos:

  1. Meu ponto não é tanto "global" > "local" quanto é "tanto faz brother, se eu quisesse salvar performance nisso não tava usando JS (muito menos game maker)". De fato, há muito pouco ganho a ser tido com esse tipo de otimização. A chance do bottleneck de performance de um programa estar em variáveis sendo locais ou globais é pífia, e se estiver, o ganho a ser tipo eliminando esse problema é imperceptível em escala macroscópica (principalmente em um jogo, onde basicamente tudo que importa é o tempo de um frame a outro). Se o foco é performance, seria muito melhor sugerir uma discussão a respeito de análise de algoritmos, gerenciamento de memória (que faça sentido, e não o óbvio "use variáveis locais") e afins (que, aliás, são relevantes até pra JS! Olha só).
  2. De fato, lendo a respeito de tempo de acesso para variáveis globais/locais em C, encontrei artigos que dizem que as variáveis locais podem ter acesso mais rápido (ou seja, podem ser vantajosas para um loop, ou coisas que usam muito frequentemente o valor da variável) justamente por estarem no stack, que devido à estrutura interna de cache do processador é mais performático em termos de acesso. Isso nem sempre é verdade, no entanto: no geral, compiladores são muito bons em fazer otimizações nesse tipo de coisa (é parte do trabalho dele afinal) e podem mudar variáveis que são muito acessadas para a stack de forma transparente. Em javascript, o problema real no acesso não é nem "local" vs "global", e sim estar dentro do mesmo bloco. Uma variável local, usada em uma função local também, tem tempo de acesso consideravelmente pior que de uma variável global. O tempo de acesso a uma variável local é melhor que o acesso a uma global, porém, e quase na mesma proporção. De todo modo, dependendo da linguagem, eu falei merda.

Tendo tirado isso do caminho, o resto do que eu disse ainda vale (e você não parece ter entendido ou se esforçado para tentar contra-argumentar). Sugiro que leia direito os pontos que dei na minha outra resposta.

E não, não recomendo usar variáveis globais: a performance pode ser pior dependendo da quantidade de acessos, a manutenabilidade é pior com certeza e, claro, se você for doente o suficiente pra colocar objetos gigantes (ou todas as suas variáveis) no escopo global, o garbage collector vai ter dificuldade pra trabalhar. Isso só não é assunto de aula.

E sim, estou sendo chato e ignorante, mas só tanto quanto ou menos que alguém sugerindo tocar no ponto super específico sobre variáveis locais em um tutorial sobre laços de repetição, onde existem VÁRIAS discussões que realmente interessam a serem feitas em termos de performance (o que acontece quando eu faço um for dentro do outro, por exemplo, em termos de tempo de execução?).

De resto, estou ciente de que vossa pessoa historicamente não demonstra capacidade de manter uma argumentação coesa e frequentemente ignora pontos levantados como réplica, então não vou me preocupar em tentar manter uma discussão.

Se te deixa satisfeito, ok, variáveis locais são melhores que globais. Você só não sabe do que está falando e eu sou intolerante com gente falando bosta ¯\_(?)_/¯

Passar bem.
 
Brandt comentou:
Vou dar o crédito que sou leigo quanto ao Game Maker, mas se o assunto é programação de software, boa sorte. Duvido, inclusive, que você tem noção do significado de otimizar um jogo (ou programa em geral).
OK_thumb.jpg
Apenas sugiro que esse assunto acabe aqui ou que outro tópico seja aberto para isso. Não quero ver tópico do Virage trancado a toa pela moderação.
 
Voltar
Topo Inferior